From 57d9bde379b5d6b8b83fa1aff354857a9b3623d2 Mon Sep 17 00:00:00 2001 From: Herb Date: Tue, 16 May 2023 03:37:12 +0900 Subject: [PATCH 01/38] =?UTF-8?q?[1=EB=8B=A8=EA=B3=84=20-=20=EC=A7=80?= =?UTF-8?q?=ED=95=98=EC=B2=A0=20=EC=A0=95=EB=B3=B4=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5]=20=ED=97=88=EB=B8=8C(=EB=B0=A9=EB=8C=80?= =?UTF-8?q?=EC=9D=98)=20=EB=AF=B8=EC=85=98=20=EC=A0=9C=EC=B6=9C=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: miseongk --- README.md | 40 ++- build.gradle | 3 +- http-request.http | 69 ++++ .../java/subway/application/LineService.java | 72 ++-- .../subway/application/StationService.java | 67 ++-- .../subway/config/DatabaseConfiguration.java | 33 ++ src/main/java/subway/dao/LineDao.java | 68 ++-- src/main/java/subway/dao/SectionDao.java | 55 +++ src/main/java/subway/dao/StationDao.java | 58 +-- src/main/java/subway/domain/Direction.java | 34 ++ src/main/java/subway/domain/Distance.java | 62 ++++ src/main/java/subway/domain/Line.java | 178 ++++++++- src/main/java/subway/domain/Section.java | 115 ++++++ src/main/java/subway/domain/Station.java | 52 ++- src/main/java/subway/domain/Subway.java | 71 ++++ .../domain/strategy/AddStationStrategy.java | 23 ++ .../strategy/AddStationToLeftStrategy.java | 27 ++ .../strategy/AddStationToRightStrategy.java | 27 ++ .../java/subway/dto/ExceptionResponse.java | 14 + .../{LineRequest.java => LineAddRequest.java} | 14 +- src/main/java/subway/dto/LineResponse.java | 30 +- .../java/subway/dto/LineUpdateRequest.java | 25 ++ .../java/subway/dto/StationDeleteRequest.java | 25 ++ .../subway/dto/StationInitialSaveRequest.java | 47 +++ src/main/java/subway/dto/StationRequest.java | 16 - src/main/java/subway/dto/StationResponse.java | 25 -- .../java/subway/dto/StationSaveRequest.java | 58 +++ src/main/java/subway/entity/LineEntity.java | 29 ++ .../java/subway/entity/SectionEntity.java | 51 +++ .../java/subway/entity/StationEntity.java | 29 ++ .../exception/DistanceNotValidException.java | 8 + .../exception/GlobalExceptionHandler.java | 51 +++ .../exception/InvalidSectionException.java | 8 + .../exception/LineAlreadyExistsException.java | 8 + .../exception/LineNotEmptyException.java | 8 + .../exception/LineNotFoundException.java | 8 + .../exception/StationNotFoundException.java | 8 + .../subway/exception/SubwayException.java | 8 + .../java/subway/repository/LineMapper.java | 76 ++++ .../subway/repository/LineRepository.java | 144 ++++++++ src/main/java/subway/ui/LineController.java | 61 ++-- .../java/subway/ui/StationController.java | 54 ++- src/main/resources/application.yml | 6 + src/main/resources/schema.sql | 33 +- .../subway/acceptance/LineAcceptanceTest.java | 175 +++++++++ .../acceptance/StationAcceptanceTest.java | 184 ++++++++++ .../subway/application/LineServiceTest.java | 159 +++++++++ .../application/StationServiceTest.java | 104 ++++++ .../java/subway/common/AcceptanceTest.java | 4 + .../java/subway/common/IntegrationTest.java | 24 ++ .../java/subway/common/steps/CommonSteps.java | 25 ++ .../java/subway/common/steps/LineSteps.java | 101 ++++++ .../subway/common/steps/SectionSteps.java | 69 ++++ src/test/java/subway/dao/LineDaoTest.java | 119 +++++++ src/test/java/subway/dao/SectionDaoTest.java | 140 ++++++++ src/test/java/subway/dao/StationDaoTest.java | 132 +++++++ .../java/subway/domain/DirectionTest.java | 42 +++ src/test/java/subway/domain/DistanceTest.java | 72 ++++ src/test/java/subway/domain/LineTest.java | 337 ++++++++++++++++++ src/test/java/subway/domain/SectionTest.java | 114 ++++++ src/test/java/subway/domain/StationTest.java | 33 ++ src/test/java/subway/domain/SubwayTest.java | 178 +++++++++ .../strategy/AddStationStrategyTest.java | 38 ++ .../AddStationToLeftStrategyTest.java | 57 +++ .../AddStationToRightStrategyTest.java | 57 +++ .../java/subway/dto/LineResponseTest.java | 37 ++ .../subway/integration/IntegrationTest.java | 19 - .../integration/LineIntegrationTest.java | 190 ---------- .../integration/StationIntegrationTest.java | 197 ---------- .../subway/repository/LineMapperTest.java | 103 ++++++ .../subway/repository/LineRepositoryTest.java | 114 ++++++ .../java/subway/ui/LineControllerTest.java | 156 ++++++++ .../java/subway/ui/StationControllerTest.java | 113 ++++++ src/test/resources/deleteAll.sql | 6 + 74 files changed, 4312 insertions(+), 685 deletions(-) create mode 100644 http-request.http create mode 100644 src/main/java/subway/config/DatabaseConfiguration.java create mode 100644 src/main/java/subway/dao/SectionDao.java create mode 100644 src/main/java/subway/domain/Direction.java create mode 100644 src/main/java/subway/domain/Distance.java create mode 100644 src/main/java/subway/domain/Section.java create mode 100644 src/main/java/subway/domain/Subway.java create mode 100644 src/main/java/subway/domain/strategy/AddStationStrategy.java create mode 100644 src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java create mode 100644 src/main/java/subway/domain/strategy/AddStationToRightStrategy.java create mode 100644 src/main/java/subway/dto/ExceptionResponse.java rename src/main/java/subway/dto/{LineRequest.java => LineAddRequest.java} (50%) create mode 100644 src/main/java/subway/dto/LineUpdateRequest.java create mode 100644 src/main/java/subway/dto/StationDeleteRequest.java create mode 100644 src/main/java/subway/dto/StationInitialSaveRequest.java delete mode 100644 src/main/java/subway/dto/StationRequest.java delete mode 100644 src/main/java/subway/dto/StationResponse.java create mode 100644 src/main/java/subway/dto/StationSaveRequest.java create mode 100644 src/main/java/subway/entity/LineEntity.java create mode 100644 src/main/java/subway/entity/SectionEntity.java create mode 100644 src/main/java/subway/entity/StationEntity.java create mode 100644 src/main/java/subway/exception/DistanceNotValidException.java create mode 100644 src/main/java/subway/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/subway/exception/InvalidSectionException.java create mode 100644 src/main/java/subway/exception/LineAlreadyExistsException.java create mode 100644 src/main/java/subway/exception/LineNotEmptyException.java create mode 100644 src/main/java/subway/exception/LineNotFoundException.java create mode 100644 src/main/java/subway/exception/StationNotFoundException.java create mode 100644 src/main/java/subway/exception/SubwayException.java create mode 100644 src/main/java/subway/repository/LineMapper.java create mode 100644 src/main/java/subway/repository/LineRepository.java create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/subway/acceptance/LineAcceptanceTest.java create mode 100644 src/test/java/subway/acceptance/StationAcceptanceTest.java create mode 100644 src/test/java/subway/application/LineServiceTest.java create mode 100644 src/test/java/subway/application/StationServiceTest.java create mode 100644 src/test/java/subway/common/AcceptanceTest.java create mode 100644 src/test/java/subway/common/IntegrationTest.java create mode 100644 src/test/java/subway/common/steps/CommonSteps.java create mode 100644 src/test/java/subway/common/steps/LineSteps.java create mode 100644 src/test/java/subway/common/steps/SectionSteps.java create mode 100644 src/test/java/subway/dao/LineDaoTest.java create mode 100644 src/test/java/subway/dao/SectionDaoTest.java create mode 100644 src/test/java/subway/dao/StationDaoTest.java create mode 100644 src/test/java/subway/domain/DirectionTest.java create mode 100644 src/test/java/subway/domain/DistanceTest.java create mode 100644 src/test/java/subway/domain/LineTest.java create mode 100644 src/test/java/subway/domain/SectionTest.java create mode 100644 src/test/java/subway/domain/StationTest.java create mode 100644 src/test/java/subway/domain/SubwayTest.java create mode 100644 src/test/java/subway/domain/strategy/AddStationStrategyTest.java create mode 100644 src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java create mode 100644 src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java create mode 100644 src/test/java/subway/dto/LineResponseTest.java delete mode 100644 src/test/java/subway/integration/IntegrationTest.java delete mode 100644 src/test/java/subway/integration/LineIntegrationTest.java delete mode 100644 src/test/java/subway/integration/StationIntegrationTest.java create mode 100644 src/test/java/subway/repository/LineMapperTest.java create mode 100644 src/test/java/subway/repository/LineRepositoryTest.java create mode 100644 src/test/java/subway/ui/LineControllerTest.java create mode 100644 src/test/java/subway/ui/StationControllerTest.java create mode 100644 src/test/resources/deleteAll.sql diff --git a/README.md b/README.md index 1a0f66ac2..9b02743a3 100644 --- a/README.md +++ b/README.md @@ -1 +1,39 @@ -# jwp-subway-path \ No newline at end of file +# jwp-subway-path + +### ๐Ÿš‡ ๋„๋ฉ”์ธ ์š”๊ตฌ์‚ฌํ•ญ + +- [x] ์—ญ ๋“ฑ๋ก + - [x] ๋ผ์ธ๋ช…, ๊ธฐ์ค€์ด ๋˜๋Š” ์—ญ, ๋“ฑ๋ก ํ•  ์—ญ, ๋ฐฉํ–ฅ, ๊ฑฐ๋ฆฌ๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์—ญ์„ ๋“ฑ๋กํ•œ๋‹ค. + - [x] ๋“ฑ๋กํ•  ์—ญ์˜ ์œ„์น˜๋Š” ์ž์œ ๋กญ๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. + - [x] ์ž…๋ ฅํ•œ ๋‘ ์—ญ์ด ์ „์ฒด ๋…ธ์„ ์—์„œ ์ด๋ฏธ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค. + - [x] ๊ธฐ์ค€์ด ๋˜๋Š” ์—ญ์€ ๊ผญ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค. + - [x] ๋“ฑ๋กํ•  ์—ญ์€ ๊ฐ™์€ ๋…ธ์„ ์—๋Š” ์กด์žฌํ•˜๋ฉด ์•ˆ๋œ๋‹ค. + - [x] ๋…ธ์„  ๊ฐ€์šด๋ฐ ์—ญ์ด ๋“ฑ๋ก๋  ๊ฒฝ์šฐ ๊ฑฐ๋ฆฌ ์ •๋ณด๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. + - [x] A-B-C ๋…ธ์„ ์—์„œ B ๋‹ค์Œ์— D ์—ญ์„ ๋“ฑ๋กํ•˜๋ ค๊ณ  ํ•  ๋•Œ B-C๊ฐ€ 3km, B-D๊ฑฐ๋ฆฌ๊ฐ€ 2km๋ผ๋ฉด B-D๊ฑฐ๋ฆฌ๋Š” 2km๋กœ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•˜๊ณ  D-C ๊ฑฐ๋ฆฌ๋Š” 1km๋กœ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•œ๋‹ค. + - [x] ์œ„์— ํ•ด๋‹นํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. +- [x] ์—ญ ์ œ๊ฑฐ + - [x] ์—ญ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒฝ์šฐ ์ •์ƒ ๋™์ž‘์„ ์œ„ํ•ด ์žฌ๋ฐฐ์น˜ ๋˜์–ด์•ผ ํ•œ๋‹ค. + - [x] ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋„ ์žฌ๋ฐฐ์ • ๋˜์–ด์•ผ ํ•œ๋‹ค. + - [x] ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์ด 2๊ฐœ ์ธ ๊ฒฝ์šฐ ์—ญ์„ ์ œ๊ฑฐํ•  ๋•Œ ๋‘ ์—ญ์ด ๋ชจ๋‘ ์ œ๊ฑฐ๋˜์–ด์•ผ ํ•œ๋‹ค. +- [x] ๋…ธ์„  ์กฐํšŒ + - [x] ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. +- [x] ์ „์ฒด ๋…ธ์„  ์กฐํšŒ + - [x] ์ „์ฒด ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. + +### ๐Ÿš‰ ์—ญ API + +| ๊ธฐ๋Šฅ | Method | URL | +|-------|--------|----------------| +| ๋“ฑ๋ก | POST | /stations | +| ์ดˆ๊ธฐ ๋“ฑ๋ก | POST | /stations/init | +| ์‚ญ์ œ | DELETE | /stations | + +### ๐Ÿ›ค๏ธ ๋…ธ์„  API + +| ๊ธฐ๋Šฅ | Method | URL | +|-------|--------|-------------| +| ์ถ”๊ฐ€ | POST | /lines | +| ์‚ญ์ œ | DELETE | /lines/{id} | +| ์ˆ˜์ • | PATCH | /lines/{id} | +| ์กฐํšŒ | GET | /lines/{id} | +| ์ „์ฒด ์กฐํšŒ | GET | /lines | diff --git a/build.gradle b/build.gradle index 68d8f2558..51eb23d2a 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' @@ -24,4 +25,4 @@ dependencies { test { useJUnitPlatform() -} \ No newline at end of file +} diff --git a/http-request.http b/http-request.http new file mode 100644 index 000000000..c06473106 --- /dev/null +++ b/http-request.http @@ -0,0 +1,69 @@ +### ๋…ธ์„  ๋“ฑ๋ก + +POST http://localhost:8080/lines +Content-Type: application/json + +{ + "name": "1ํ˜ธ์„ ", + "color": "RED" +} + +### ๋…ธ์„  ์ˆ˜์ • + +PATCH http://localhost:8080/lines/1 +Content-Type: application/json + +{ + "name": "2ํ˜ธ์„ ", + "color": "RED" +} + +### ๋…ธ์„  ์‚ญ์ œ + +DELETE http://localhost:8080/lines/1 +Content-Type: application/json + +### ๋…ธ์„  ์ „์ฒด ์กฐํšŒ + +GET http://localhost:8080/lines +Content-Type: application/json + +### ๋…ธ์„  ๋‹จ์ผ ์กฐํšŒ + +GET http://localhost:8080/lines/1 +Content-Type: application/json + +### ์—ญ ์ดˆ๊ธฐ ๋“ฑ๋ก + +POST http://localhost:8080/stations/init +Content-Type: application/json + +{ + "lineName": "1ํ˜ธ์„ ", + "leftStationName": "A", + "rightStationName": "B", + "distance": 3 +} + +### ์—ญ ๋“ฑ๋ก + +POST http://localhost:8080/stations +Content-Type: application/json + +{ + "lineName": "1ํ˜ธ์„ ", + "baseStationName": "B", + "additionalStationName": "C", + "direction": "RIGHT", + "distance": 3 +} + +### ์—ญ ์ œ๊ฑฐ + +DELETE http://localhost:8080/stations +Content-Type: application/json + +{ + "lineName": "1ํ˜ธ์„ ", + "stationName": "B" +} diff --git a/src/main/java/subway/application/LineService.java b/src/main/java/subway/application/LineService.java index bdb006f53..3e167f2c5 100644 --- a/src/main/java/subway/application/LineService.java +++ b/src/main/java/subway/application/LineService.java @@ -1,53 +1,63 @@ package subway.application; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; import org.springframework.stereotype.Service; -import subway.dao.LineDao; +import org.springframework.transaction.annotation.Transactional; import subway.domain.Line; -import subway.dto.LineRequest; +import subway.dto.LineAddRequest; import subway.dto.LineResponse; +import subway.dto.LineUpdateRequest; +import subway.exception.LineAlreadyExistsException; +import subway.exception.LineNotFoundException; +import subway.repository.LineRepository; -import java.util.List; -import java.util.stream.Collectors; - +@Transactional @Service public class LineService { - private final LineDao lineDao; - public LineService(LineDao lineDao) { - this.lineDao = lineDao; - } - - public LineResponse saveLine(LineRequest request) { - Line persistLine = lineDao.insert(new Line(request.getName(), request.getColor())); - return LineResponse.of(persistLine); - } + private final LineRepository lineRepository; - public List findLineResponses() { - List persistLines = findLines(); - return persistLines.stream() - .map(LineResponse::of) - .collect(Collectors.toList()); + public LineService(final LineRepository lineRepository) { + this.lineRepository = lineRepository; } - public List findLines() { - return lineDao.findAll(); + public Long add(final LineAddRequest request) { + final Optional lineId = lineRepository.findIdByName(request.getName()); + if (lineId.isPresent()) { + throw new LineAlreadyExistsException(); + } + return lineRepository.save(new Line(request.getName(), request.getColor(), Collections.emptyList())) + .getId(); } - public LineResponse findLineResponseById(Long id) { - Line persistLine = findLineById(id); - return LineResponse.of(persistLine); + public void delete(final Long id) { + lineRepository.findById(id) + .orElseThrow(LineNotFoundException::new); + lineRepository.deleteById(id); } - public Line findLineById(Long id) { - return lineDao.findById(id); + public void update(final Long id, final LineUpdateRequest request) { + final Line line = lineRepository.findById(id) + .orElseThrow(LineNotFoundException::new); + line.changeNameAndColor(request.getName(), request.getColor()); + lineRepository.save(line); } - public void updateLine(Long id, LineRequest lineUpdateRequest) { - lineDao.update(new Line(id, lineUpdateRequest.getName(), lineUpdateRequest.getColor())); + @Transactional(readOnly = true) + public LineResponse findById(final Long id) { + final Line line = lineRepository.findById(id) + .orElseThrow(LineNotFoundException::new); + return LineResponse.from(line); } - public void deleteLineById(Long id) { - lineDao.deleteById(id); + @Transactional(readOnly = true) + public List findAll() { + return lineRepository.findAll().stream() + .map(LineResponse::from) + .collect(toList()); } - } diff --git a/src/main/java/subway/application/StationService.java b/src/main/java/subway/application/StationService.java index 603d9daa7..c56f52415 100644 --- a/src/main/java/subway/application/StationService.java +++ b/src/main/java/subway/application/StationService.java @@ -1,44 +1,55 @@ package subway.application; import org.springframework.stereotype.Service; -import subway.dao.StationDao; -import subway.domain.Station; -import subway.dto.StationRequest; -import subway.dto.StationResponse; - -import java.util.List; -import java.util.stream.Collectors; - +import org.springframework.transaction.annotation.Transactional; +import subway.domain.Line; +import subway.domain.Subway; +import subway.dto.StationDeleteRequest; +import subway.dto.StationInitialSaveRequest; +import subway.dto.StationSaveRequest; +import subway.repository.LineRepository; + +@Transactional @Service public class StationService { - private final StationDao stationDao; - public StationService(StationDao stationDao) { - this.stationDao = stationDao; - } + private final LineRepository lineRepository; - public StationResponse saveStation(StationRequest stationRequest) { - Station station = stationDao.insert(new Station(stationRequest.getName())); - return StationResponse.of(station); + public StationService(final LineRepository lineRepository) { + this.lineRepository = lineRepository; } - public StationResponse findStationResponseById(Long id) { - return StationResponse.of(stationDao.findById(id)); + public void initialSave(final StationInitialSaveRequest request) { + final Subway subway = new Subway(lineRepository.findAll()); + subway.initialAdd( + request.getLineName(), + request.getLeftStationName(), + request.getRightStationName(), + request.getDistance() + ); + saveLine(subway, request.getLineName()); } - public List findAllStationResponses() { - List stations = stationDao.findAll(); - - return stations.stream() - .map(StationResponse::of) - .collect(Collectors.toList()); + private void saveLine(final Subway subway, final String request) { + final Line line = subway.findLineByName(request); + lineRepository.save(line); } - public void updateStation(Long id, StationRequest stationRequest) { - stationDao.update(new Station(id, stationRequest.getName())); + public void save(final StationSaveRequest request) { + final Subway subway = new Subway(lineRepository.findAll()); + subway.add( + request.getLineName(), + request.getBaseStationName(), + request.getAdditionalStationName(), + request.getDistance(), + request.getDirection() + ); + saveLine(subway, request.getLineName()); } - public void deleteStationById(Long id) { - stationDao.deleteById(id); + public void delete(final StationDeleteRequest request) { + final Subway subway = new Subway(lineRepository.findAll()); + subway.remove(request.getLineName(), request.getStationName()); + saveLine(subway, request.getLineName()); } -} \ No newline at end of file +} diff --git a/src/main/java/subway/config/DatabaseConfiguration.java b/src/main/java/subway/config/DatabaseConfiguration.java new file mode 100644 index 000000000..008efd636 --- /dev/null +++ b/src/main/java/subway/config/DatabaseConfiguration.java @@ -0,0 +1,33 @@ +package subway.config; + +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DatabaseConfiguration { + + @Value("${my.datasource.url}") + private String url; + + @Value("${my.datasource.driver-class-name}") + private String driverClassName; + + @Value("${my.datasource.username}") + private String userName; + + @Value("${my.datasource.password}") + private String password; + + @Bean + public DataSource dataSource() { + return DataSourceBuilder.create() + .url(url) + .driverClassName(driverClassName) + .username(userName) + .password(password) + .build(); + } +} diff --git a/src/main/java/subway/dao/LineDao.java b/src/main/java/subway/dao/LineDao.java index f644bac29..37f77f9e4 100644 --- a/src/main/java/subway/dao/LineDao.java +++ b/src/main/java/subway/dao/LineDao.java @@ -1,61 +1,69 @@ package subway.dao; +import java.util.List; +import java.util.Optional; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.stereotype.Repository; -import subway.domain.Line; - -import javax.sql.DataSource; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import subway.entity.LineEntity; @Repository public class LineDao { - private final JdbcTemplate jdbcTemplate; - private final SimpleJdbcInsert insertAction; - private RowMapper rowMapper = (rs, rowNum) -> - new Line( + private final JdbcTemplate jdbcTemplate; + private final SimpleJdbcInsert jdbcInsert; + private final RowMapper rowMapper = (rs, rowNum) -> + new LineEntity( rs.getLong("id"), rs.getString("name"), rs.getString("color") ); - public LineDao(JdbcTemplate jdbcTemplate, DataSource dataSource) { + public LineDao(final JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; - this.insertAction = new SimpleJdbcInsert(dataSource) + this.jdbcInsert = new SimpleJdbcInsert(jdbcTemplate) .withTableName("line") .usingGeneratedKeyColumns("id"); } - public Line insert(Line line) { - Map params = new HashMap<>(); - params.put("id", line.getId()); - params.put("name", line.getName()); - params.put("color", line.getColor()); - - Long lineId = insertAction.executeAndReturnKey(params).longValue(); - return new Line(lineId, line.getName(), line.getColor()); + public LineEntity insert(final LineEntity line) { + final BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(line); + Long lineId = jdbcInsert.executeAndReturnKey(parameterSource).longValue(); + return new LineEntity(lineId, line.getName(), line.getColor()); } - public List findAll() { - String sql = "select id, name, color from LINE"; + public List findAll() { + String sql = "SELECT id, name, color FROM LINE"; return jdbcTemplate.query(sql, rowMapper); } - public Line findById(Long id) { - String sql = "select id, name, color from LINE WHERE id = ?"; - return jdbcTemplate.queryForObject(sql, rowMapper, id); + public Optional findById(final Long id) { + String sql = "SELECT id, name, color FROM LINE WHERE id = ?"; + try { + return Optional.ofNullable(jdbcTemplate.queryForObject(sql, rowMapper, id)); + } catch (final EmptyResultDataAccessException e) { + return Optional.empty(); + } + } + + public Optional findByName(final String name) { + String sql = "SELECT id, name, color FROM LINE WHERE name = ?"; + try { + return Optional.ofNullable(jdbcTemplate.queryForObject(sql, rowMapper, name)); + } catch (final EmptyResultDataAccessException e) { + return Optional.empty(); + } } - public void update(Line newLine) { - String sql = "update LINE set name = ?, color = ? where id = ?"; - jdbcTemplate.update(sql, new Object[]{newLine.getName(), newLine.getColor(), newLine.getId()}); + public void update(final LineEntity newLine) { + String sql = "UPDATE LINE SET name = ?, color = ? WHERE id = ?"; + jdbcTemplate.update(sql, newLine.getName(), newLine.getColor(), newLine.getId()); } - public void deleteById(Long id) { - jdbcTemplate.update("delete from Line where id = ?", id); + public void deleteById(final Long id) { + jdbcTemplate.update("DELETE FROM Line WHERE id = ?", id); } } diff --git a/src/main/java/subway/dao/SectionDao.java b/src/main/java/subway/dao/SectionDao.java new file mode 100644 index 000000000..10a47aedf --- /dev/null +++ b/src/main/java/subway/dao/SectionDao.java @@ -0,0 +1,55 @@ +package subway.dao; + +import java.util.List; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; +import subway.entity.SectionEntity; + +@Repository +public class SectionDao { + + private final JdbcTemplate jdbcTemplate; + private final RowMapper rowMapper = (rs, rowNum) -> + new SectionEntity( + rs.getLong("id"), + rs.getLong("start_station_id"), + rs.getLong("end_station_id"), + rs.getInt("distance"), + rs.getLong("line_id") + ); + + public SectionDao(final JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public List findAll() { + final String sql = "SELECT * FROM section"; + return jdbcTemplate.query(sql, rowMapper); + } + + public void insertAll(final List sections) { + final String sql = "INSERT INTO section (start_station_id, end_station_id, distance, line_id) VALUES (?, ?, ?, ?)"; + jdbcTemplate.batchUpdate(sql, sections, sections.size(), ((ps, section) -> { + ps.setLong(1, section.getStartStationId()); + ps.setLong(2, section.getEndStationId()); + ps.setInt(3, section.getDistance()); + ps.setLong(4, section.getLineId()); + })); + } + + public void deleteAllByLineId(final Long lineId) { + final String sql = "DELETE FROM section WHERE line_id = ?"; + jdbcTemplate.update(sql, lineId); + } + + public List findByLineId(final Long lineId) { + final String sql = "SELECT * FROM section WHERE line_id = ?"; + return jdbcTemplate.query(sql, rowMapper, lineId); + } + + public void deleteById(final Long id) { + final String sql = "DELETE FROM section WHERE id = ?"; + jdbcTemplate.update(sql, id); + } +} diff --git a/src/main/java/subway/dao/StationDao.java b/src/main/java/subway/dao/StationDao.java index 07f7eab30..c8c3b2c30 100644 --- a/src/main/java/subway/dao/StationDao.java +++ b/src/main/java/subway/dao/StationDao.java @@ -1,58 +1,62 @@ package subway.dao; +import java.util.List; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.stereotype.Repository; -import subway.domain.Station; - -import javax.sql.DataSource; -import java.util.List; +import subway.entity.StationEntity; @Repository public class StationDao { - private final JdbcTemplate jdbcTemplate; - private final SimpleJdbcInsert insertAction; - private RowMapper rowMapper = (rs, rowNum) -> - new Station( + private final JdbcTemplate jdbcTemplate; + private final SimpleJdbcInsert jdbcInsert; + private final RowMapper rowMapper = (rs, rowNum) -> + new StationEntity( rs.getLong("id"), - rs.getString("name") + rs.getString("name"), + rs.getLong("line_id") ); - - public StationDao(JdbcTemplate jdbcTemplate, DataSource dataSource) { + public StationDao(final JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; - this.insertAction = new SimpleJdbcInsert(dataSource) + this.jdbcInsert = new SimpleJdbcInsert(jdbcTemplate) .withTableName("station") .usingGeneratedKeyColumns("id"); } - public Station insert(Station station) { - SqlParameterSource params = new BeanPropertySqlParameterSource(station); - Long id = insertAction.executeAndReturnKey(params).longValue(); - return new Station(id, station.getName()); + public void insertAll(final List stations) { + final BeanPropertySqlParameterSource[] parameterSources = stations.stream() + .map(BeanPropertySqlParameterSource::new) + .toArray(BeanPropertySqlParameterSource[]::new); + jdbcInsert.executeBatch(parameterSources); + } + + public StationEntity insert(final StationEntity stations) { + final BeanPropertySqlParameterSource parameterSources = new BeanPropertySqlParameterSource(stations); + Long id = jdbcInsert.executeAndReturnKey(parameterSources).longValue(); + return new StationEntity(id, stations.getName(), stations.getLineId()); } - public List findAll() { - String sql = "select * from STATION"; + public List findAll() { + String sql = "SELECT * FROM STATION"; return jdbcTemplate.query(sql, rowMapper); } - public Station findById(Long id) { - String sql = "select * from STATION where id = ?"; - return jdbcTemplate.queryForObject(sql, rowMapper, id); + public void deleteByLineId(final Long lineId) { + String sql = "DELETE FROM STATION WHERE line_id = ?"; + jdbcTemplate.update(sql, lineId); } - public void update(Station newStation) { - String sql = "update STATION set name = ? where id = ?"; - jdbcTemplate.update(sql, new Object[]{newStation.getName(), newStation.getId()}); + public List findByLineId(final Long lineId) { + String sql = "SELECT * FROM STATION where line_id = ?"; + return jdbcTemplate.query(sql, rowMapper, lineId); } - public void deleteById(Long id) { - String sql = "delete from STATION where id = ?"; + public void deleteById(final Long id) { + String sql = "DELETE FROM STATION WHERE id = ?"; jdbcTemplate.update(sql, id); } } diff --git a/src/main/java/subway/domain/Direction.java b/src/main/java/subway/domain/Direction.java new file mode 100644 index 000000000..58e4c9a29 --- /dev/null +++ b/src/main/java/subway/domain/Direction.java @@ -0,0 +1,34 @@ +package subway.domain; + +import java.util.List; +import subway.domain.strategy.AddStationStrategy; +import subway.domain.strategy.AddStationToLeftStrategy; +import subway.domain.strategy.AddStationToRightStrategy; + +public enum Direction { + LEFT(new AddStationToLeftStrategy()), + RIGHT(new AddStationToRightStrategy()), + ; + + private final AddStationStrategy addStationStrategy; + + Direction(final AddStationStrategy addStationStrategy) { + this.addStationStrategy = addStationStrategy; + } + + public Direction flip() { + if (this == LEFT) { + return RIGHT; + } + return LEFT; + } + + public void addStation( + final List
sections, + final Station base, + final Station additional, + final Distance distance + ) { + addStationStrategy.add(sections, base, additional, distance); + } +} diff --git a/src/main/java/subway/domain/Distance.java b/src/main/java/subway/domain/Distance.java new file mode 100644 index 000000000..c46b591d0 --- /dev/null +++ b/src/main/java/subway/domain/Distance.java @@ -0,0 +1,62 @@ +package subway.domain; + +import java.util.Objects; +import subway.exception.DistanceNotValidException; + +public class Distance { + + private static final int MINIMUM_DISTANCE_VALUE = 1; + + private final int value; + + public Distance(final int value) { + validate(value); + this.value = value; + } + + private void validate(final int value) { + if (value < MINIMUM_DISTANCE_VALUE) { + throw new DistanceNotValidException(); + } + } + + public boolean moreThanOrEqual(final Distance distance) { + return value <= distance.value; + } + + public Distance subtract(final Distance distance) { + return new Distance(value - distance.value); + } + + public Distance add(final Distance distance) { + return new Distance(value + distance.value); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Distance distance = (Distance) o; + return value == distance.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "Distance{" + + "value=" + value + + '}'; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index 699d0b6df..51c54e735 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,26 +1,181 @@ package subway.domain; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static subway.domain.Direction.LEFT; +import static subway.domain.Direction.RIGHT; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; +import subway.exception.InvalidSectionException; +import subway.exception.LineNotEmptyException; +import subway.exception.StationNotFoundException; public class Line { - private Long id; + + private final Long id; private String name; private String color; + private final List
sections; - public Line() { + public Line(final String name, final String color, final List
sections) { + this(null, name, color, sections); } - public Line(String name, String color) { + public Line(final Long id, final String name, final String color, final List
sections) { + this.id = id; this.name = name; this.color = color; + this.sections = new ArrayList<>(sections); } - public Line(Long id, String name, String color) { - this.id = id; + public boolean containsAll(final Station start, final Station end) { + return sections.stream() + .anyMatch(section -> section.containsAll(start, end)); + } + + public void add(final Station base, final Station additional, final Distance distance, final Direction direction) { + validate(base, additional, distance, direction); + direction.addStation(sections, base, additional, distance); + } + + private void validate( + final Station base, + final Station additional, + final Distance distance, + final Direction direction + ) { + if (!contains(base)) { + throw new InvalidSectionException("๊ธฐ์ค€์—ญ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + if (contains(additional)) { + throw new InvalidSectionException("๋“ฑ๋กํ•  ์—ญ์ด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."); + } + if (isInvalidDistance(base, distance, direction)) { + throw new InvalidSectionException("๋“ฑ๋กํ•  ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ธฐ์กด ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private boolean contains(final Station station) { + return sections.stream() + .anyMatch(section -> section.contains(station)); + } + + private boolean isInvalidDistance(final Station base, final Distance distance, final Direction direction) { + return findSectionByStationExistsAtDirection(base, direction.flip()) + .map(section -> section.moreThanOrEqual(distance)) + .orElse(false); + } + + private Optional
findSectionByStationExistsAtDirection(final Station base, final Direction direction) { + return sections.stream() + .filter(section -> section.isStationExistsAtDirection(base, direction)) + .findFirst(); + } + + public boolean isSameName(final String lineName) { + return name.equals(lineName); + } + + public void remove(final Station station) { + if (!contains(station)) { + throw new StationNotFoundException(); + } + + final Optional
sectionAtLeft = findSectionByStationExistsAtDirection(station, RIGHT); + final Optional
sectionAtRight = findSectionByStationExistsAtDirection(station, LEFT); + + if (sectionAtLeft.isPresent() && sectionAtRight.isPresent()) { + final Section left = sectionAtLeft.get(); + final Section right = sectionAtRight.get(); + sections.add(new Section(left.getStart(), right.getEnd(), left.add(right.getDistance()))); + } + + sectionAtLeft.ifPresent(sections::remove); + sectionAtRight.ifPresent(sections::remove); + } + + public List findAllStation() { + final Map stationToStation = sections.stream() + .collect(toMap(Section::getStartName, Section::getEndName)); + + final Optional firstStationName = findFirstStation(stationToStation); + return firstStationName.map(station -> orderStations(stationToStation, station)) + .orElse(Collections.emptyList()); + } + + private Optional findFirstStation(final Map stationToStation) { + final Set stations = new HashSet<>(stationToStation.keySet()); + stations.removeAll(stationToStation.values()); + return stations.stream().findFirst(); + } + + private List orderStations(final Map stationToStation, String station) { + final List result = new ArrayList<>(List.of(station)); + while (stationToStation.containsKey(station)) { + final String next = stationToStation.get(station); + result.add(next); + station = next; + } + return result.stream() + .map(this::findStationByName) + .collect(toList()); + } + + public void initialAdd(final Section section) { + if (!sections.isEmpty()) { + throw new LineNotEmptyException(); + } + sections.add(section); + } + + public void changeNameAndColor(final String name, final String color) { this.name = name; this.color = color; } + public Station findStationByName(final String name) { + return sections.stream() + .flatMap(section -> Stream.of(section.getStart(), section.getEnd())) + .filter(station -> station.isSameName(name)) + .findFirst() + .orElseThrow(StationNotFoundException::new); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Line line = (Line) o; + return Objects.equals(id, line.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Line{" + + "id=" + id + + ", name='" + name + '\'' + + ", color='" + color + '\'' + + ", sections=" + sections + + '}'; + } + public Long getId() { return id; } @@ -33,16 +188,7 @@ public String getColor() { return color; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Line line = (Line) o; - return Objects.equals(id, line.id) && Objects.equals(name, line.name) && Objects.equals(color, line.color); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, color); + public List
getSections() { + return sections; } } diff --git a/src/main/java/subway/domain/Section.java b/src/main/java/subway/domain/Section.java new file mode 100644 index 000000000..ee2388a6f --- /dev/null +++ b/src/main/java/subway/domain/Section.java @@ -0,0 +1,115 @@ +package subway.domain; + +import static subway.domain.Direction.LEFT; + +import java.util.Objects; + +public class Section { + + private final Long id; + private final Station start; + private final Station end; + private final Distance distance; + + public Section(final String start, final String end, final int distance) { + this(null, new Station(start), new Station(end), new Distance(distance)); + } + + public Section(final Station start, final Station end, final Distance distance) { + this(null, start, end, distance); + } + + public Section(final Long id, final String start, final String end, final int distance) { + this(id, new Station(start), new Station(end), new Distance(distance)); + } + + public Section(final Long id, final Station start, final Station end, final Distance distance) { + this.id = id; + this.start = start; + this.end = end; + this.distance = distance; + } + + public boolean contains(final Station station) { + return start.isSameName(station) || end.isSameName(station); + } + + public boolean containsAll(final Station start, final Station end) { + return (this.start.isSameName(start) && this.end.isSameName(end)) + || (this.start.isSameName(end) && this.end.isSameName(start)); + } + + public boolean moreThanOrEqual(final Distance distance) { + return this.distance.moreThanOrEqual(distance); + } + + public boolean isStationExistsAtDirection(final Station station, final Direction direction) { + if (direction == LEFT) { + return start.isSameName(station); + } + return end.isSameName(station); + } + + public Distance subtract(final Distance distance) { + return this.distance.subtract(distance); + } + + public Distance add(final Distance distance) { + return this.distance.add(distance); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Section section = (Section) o; + return Objects.equals(id, section.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Section{" + + "id=" + id + + ", start=" + start + + ", end=" + end + + ", distance=" + distance + + '}'; + } + + public Long getId() { + return id; + } + + public Station getStart() { + return start; + } + + public String getStartName() { + return start.getName(); + } + + public Station getEnd() { + return end; + } + + public String getEndName() { + return end.getName(); + } + + public Distance getDistance() { + return distance; + } + + public Integer getDistanceValue() { + return distance.getValue(); + } +} diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index dbf9d7835..497f561db 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -3,39 +3,57 @@ import java.util.Objects; public class Station { - private Long id; - private String name; - public Station() { + private final Long id; + private final String name; + + public Station(final String name) { + this(null, name); } - public Station(Long id, String name) { + public Station(final Long id, final String name) { this.id = id; this.name = name; } - public Station(String name) { - this.name = name; + public boolean isSameName(final String name) { + return this.name.equals(name); } - public Long getId() { - return id; + public boolean isSameName(final Station other) { + return name.equals(other.name); } - public String getName() { - return name; + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Station station = (Station) o; + return Objects.equals(id, station.id); } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Station station = (Station) o; - return id.equals(station.id) && name.equals(station.name); + public int hashCode() { + return Objects.hash(id); } @Override - public int hashCode() { - return Objects.hash(id, name); + public String toString() { + return "Station{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; } } diff --git a/src/main/java/subway/domain/Subway.java b/src/main/java/subway/domain/Subway.java new file mode 100644 index 000000000..c21688254 --- /dev/null +++ b/src/main/java/subway/domain/Subway.java @@ -0,0 +1,71 @@ +package subway.domain; + +import java.util.ArrayList; +import java.util.List; +import subway.exception.InvalidSectionException; +import subway.exception.LineNotFoundException; + +public class Subway { + + private final List lines; + + public Subway(final List lines) { + this.lines = new ArrayList<>(lines); + } + + public void add( + final String lineName, + final String baseStationName, + final String additionalStationName, + final int distanceValue, + final Direction direction + ) { + final Station base = new Station(baseStationName); + final Station additional = new Station(additionalStationName); + final Distance distance = new Distance(distanceValue); + + if (lines.stream().anyMatch(line -> line.containsAll(base, additional))) { + throw new InvalidSectionException("์ง€ํ•˜์ฒ  ์ „์ฒด ๋…ธ์„ ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค."); + } + + final Line findLine = findLineByName(lineName); + final Station baseStation = findLine.findStationByName(baseStationName); + findLine.add(baseStation, additional, distance, direction); + } + + public Line findLineByName(final String name) { + return lines.stream() + .filter(line -> line.isSameName(name)) + .findFirst() + .orElseThrow(LineNotFoundException::new); + } + + public void remove(final String lineName, final String stationName) { + final Line findLine = findLineByName(lineName); + findLine.remove(new Station(stationName)); + } + + public void initialAdd( + final String lineName, + final String leftStationName, + final String rightStationName, + final Integer distance + ) { + if (leftStationName.equals(rightStationName)) { + throw new InvalidSectionException("๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์—ญ์„ ๊ตฌ๊ฐ„์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + final Station left = new Station(leftStationName); + final Station right = new Station(rightStationName); + + if (lines.stream().anyMatch(line -> line.containsAll(left, right))) { + throw new InvalidSectionException("์ง€ํ•˜์ฒ  ์ „์ฒด ๋…ธ์„ ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค."); + } + + final Line findLine = findLineByName(lineName); + findLine.initialAdd(new Section(left, right, new Distance((distance)))); + } + + public List getLines() { + return lines; + } +} diff --git a/src/main/java/subway/domain/strategy/AddStationStrategy.java b/src/main/java/subway/domain/strategy/AddStationStrategy.java new file mode 100644 index 000000000..7fee18e20 --- /dev/null +++ b/src/main/java/subway/domain/strategy/AddStationStrategy.java @@ -0,0 +1,23 @@ +package subway.domain.strategy; + +import java.util.List; +import java.util.Optional; +import subway.domain.Direction; +import subway.domain.Distance; +import subway.domain.Section; +import subway.domain.Station; + +public interface AddStationStrategy { + + void add(final List
sections, final Station base, final Station additional, final Distance distance); + + default Optional
findSectionByStationExistsAtDirection( + final List
sections, + final Station station, + final Direction direction + ) { + return sections.stream() + .filter(section -> section.isStationExistsAtDirection(station, direction)) + .findFirst(); + } +} diff --git a/src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java b/src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java new file mode 100644 index 000000000..cc87bbb10 --- /dev/null +++ b/src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java @@ -0,0 +1,27 @@ +package subway.domain.strategy; + +import static subway.domain.Direction.RIGHT; + +import java.util.List; +import java.util.Optional; +import subway.domain.Distance; +import subway.domain.Section; +import subway.domain.Station; + +public class AddStationToLeftStrategy implements AddStationStrategy { + @Override + public void add( + final List
sections, + final Station base, + final Station additional, + final Distance distance + ) { + final Optional
section = findSectionByStationExistsAtDirection(sections, base, RIGHT); + if (section.isPresent()) { + final Section originSection = section.get(); + sections.add(new Section(originSection.getStart(), additional, originSection.subtract(distance))); + sections.remove(originSection); + } + sections.add(new Section(additional, base, distance)); + } +} diff --git a/src/main/java/subway/domain/strategy/AddStationToRightStrategy.java b/src/main/java/subway/domain/strategy/AddStationToRightStrategy.java new file mode 100644 index 000000000..d5db5e6ff --- /dev/null +++ b/src/main/java/subway/domain/strategy/AddStationToRightStrategy.java @@ -0,0 +1,27 @@ +package subway.domain.strategy; + +import static subway.domain.Direction.LEFT; + +import java.util.List; +import java.util.Optional; +import subway.domain.Distance; +import subway.domain.Section; +import subway.domain.Station; + +public class AddStationToRightStrategy implements AddStationStrategy { + @Override + public void add( + final List
sections, + final Station base, + final Station additional, + final Distance distance + ) { + final Optional
section = findSectionByStationExistsAtDirection(sections, base, LEFT); + if (section.isPresent()) { + final Section originSection = section.get(); + sections.add(new Section(additional, originSection.getEnd(), originSection.subtract(distance))); + sections.remove(originSection); + } + sections.add(new Section(base, additional, distance)); + } +} diff --git a/src/main/java/subway/dto/ExceptionResponse.java b/src/main/java/subway/dto/ExceptionResponse.java new file mode 100644 index 000000000..ce2cdb5ae --- /dev/null +++ b/src/main/java/subway/dto/ExceptionResponse.java @@ -0,0 +1,14 @@ +package subway.dto; + +public class ExceptionResponse { + + private final String message; + + public ExceptionResponse(final String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/subway/dto/LineRequest.java b/src/main/java/subway/dto/LineAddRequest.java similarity index 50% rename from src/main/java/subway/dto/LineRequest.java rename to src/main/java/subway/dto/LineAddRequest.java index 16cb5bf76..a8e919fdf 100644 --- a/src/main/java/subway/dto/LineRequest.java +++ b/src/main/java/subway/dto/LineAddRequest.java @@ -1,13 +1,16 @@ package subway.dto; -public class LineRequest { +import javax.validation.constraints.NotBlank; + +public class LineAddRequest { + + @NotBlank(message = "๋…ธ์„ ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") private String name; - private String color; - public LineRequest() { - } + @NotBlank(message = "๋…ธ์„  ์ƒ‰์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private String color; - public LineRequest(String name, String color) { + public LineAddRequest(String name, String color) { this.name = name; this.color = color; } @@ -19,5 +22,4 @@ public String getName() { public String getColor() { return color; } - } diff --git a/src/main/java/subway/dto/LineResponse.java b/src/main/java/subway/dto/LineResponse.java index c9b668122..1fc5c5dce 100644 --- a/src/main/java/subway/dto/LineResponse.java +++ b/src/main/java/subway/dto/LineResponse.java @@ -1,24 +1,28 @@ package subway.dto; +import static java.util.stream.Collectors.toList; + +import java.util.List; import subway.domain.Line; +import subway.domain.Station; public class LineResponse { - private Long id; - private String name; - private String color; - public LineResponse(Long id, String name, String color) { - this.id = id; + private final String name; + private final String color; + private final List stations; + + public LineResponse(final String name, final String color, final List stations) { this.name = name; this.color = color; + this.stations = stations; } - public static LineResponse of(Line line) { - return new LineResponse(line.getId(), line.getName(), line.getColor()); - } - - public Long getId() { - return id; + public static LineResponse from(final Line line) { + final List names = line.findAllStation().stream() + .map(Station::getName) + .collect(toList()); + return new LineResponse(line.getName(), line.getColor(), names); } public String getName() { @@ -28,4 +32,8 @@ public String getName() { public String getColor() { return color; } + + public List getStations() { + return stations; + } } diff --git a/src/main/java/subway/dto/LineUpdateRequest.java b/src/main/java/subway/dto/LineUpdateRequest.java new file mode 100644 index 000000000..71ef633a9 --- /dev/null +++ b/src/main/java/subway/dto/LineUpdateRequest.java @@ -0,0 +1,25 @@ +package subway.dto; + +import javax.validation.constraints.NotBlank; + +public class LineUpdateRequest { + + @NotBlank(message = "๋…ธ์„ ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private String name; + + @NotBlank(message = "๋…ธ์„  ์ƒ‰์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private String color; + + public LineUpdateRequest(String name, String color) { + this.name = name; + this.color = color; + } + + public String getName() { + return name; + } + + public String getColor() { + return color; + } +} diff --git a/src/main/java/subway/dto/StationDeleteRequest.java b/src/main/java/subway/dto/StationDeleteRequest.java new file mode 100644 index 000000000..d5d996bc7 --- /dev/null +++ b/src/main/java/subway/dto/StationDeleteRequest.java @@ -0,0 +1,25 @@ +package subway.dto; + +import javax.validation.constraints.NotBlank; + +public class StationDeleteRequest { + + @NotBlank(message = "๋…ธ์„ ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String lineName; + + @NotBlank(message = "์—ญ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String stationName; + + public StationDeleteRequest(final String lineName, final String stationName) { + this.lineName = lineName; + this.stationName = stationName; + } + + public String getLineName() { + return lineName; + } + + public String getStationName() { + return stationName; + } +} diff --git a/src/main/java/subway/dto/StationInitialSaveRequest.java b/src/main/java/subway/dto/StationInitialSaveRequest.java new file mode 100644 index 000000000..073b7993a --- /dev/null +++ b/src/main/java/subway/dto/StationInitialSaveRequest.java @@ -0,0 +1,47 @@ +package subway.dto; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Positive; + +public class StationInitialSaveRequest { + + @NotBlank(message = "๋…ธ์„ ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String lineName; + + @NotBlank(message = "์‹œ์ž‘์—ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String leftStationName; + + @NotBlank(message = "๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String rightStationName; + + @Positive(message = "๋“ฑ๋กํ•  ๊ฑฐ๋ฆฌ๋Š” ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private final Integer distance; + + public StationInitialSaveRequest( + final String lineName, + final String leftStationName, + final String rightStationName, + final Integer distance + ) { + this.lineName = lineName; + this.leftStationName = leftStationName; + this.rightStationName = rightStationName; + this.distance = distance; + } + + public String getLineName() { + return lineName; + } + + public String getLeftStationName() { + return leftStationName; + } + + public String getRightStationName() { + return rightStationName; + } + + public Integer getDistance() { + return distance; + } +} diff --git a/src/main/java/subway/dto/StationRequest.java b/src/main/java/subway/dto/StationRequest.java deleted file mode 100644 index 15175303d..000000000 --- a/src/main/java/subway/dto/StationRequest.java +++ /dev/null @@ -1,16 +0,0 @@ -package subway.dto; - -public class StationRequest { - private String name; - - public StationRequest() { - } - - public StationRequest(String name) { - this.name = name; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/subway/dto/StationResponse.java b/src/main/java/subway/dto/StationResponse.java deleted file mode 100644 index 5eec02fe0..000000000 --- a/src/main/java/subway/dto/StationResponse.java +++ /dev/null @@ -1,25 +0,0 @@ -package subway.dto; - -import subway.domain.Station; - -public class StationResponse { - private Long id; - private String name; - - public StationResponse(Long id, String name) { - this.id = id; - this.name = name; - } - - public static StationResponse of(Station station) { - return new StationResponse(station.getId(), station.getName()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/subway/dto/StationSaveRequest.java b/src/main/java/subway/dto/StationSaveRequest.java new file mode 100644 index 000000000..1e80b1ab0 --- /dev/null +++ b/src/main/java/subway/dto/StationSaveRequest.java @@ -0,0 +1,58 @@ +package subway.dto; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; +import subway.domain.Direction; + +public class StationSaveRequest { + + @NotBlank(message = "๋…ธ์„ ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String lineName; + + @NotBlank(message = "๊ธฐ์ค€์—ญ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String baseStationName; + + @NotBlank(message = "๋“ฑ๋กํ•  ์—ญ๋ช…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String additionalStationName; + + @NotNull(message = "์™ผ์ชฝ์œผ๋กœ ๋“ฑ๋กํ•  ๊ฒฝ์šฐ LEFT, ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋“ฑ๋กํ•  ๊ฒฝ์šฐ RIGHT๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final Direction direction; + + @Positive(message = "๋“ฑ๋กํ•  ๊ฑฐ๋ฆฌ๋Š” ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private final Integer distance; + + public StationSaveRequest( + final String lineName, + final String baseStationName, + final String additionalStationName, + final Direction direction, + final Integer distance + ) { + this.lineName = lineName; + this.baseStationName = baseStationName; + this.additionalStationName = additionalStationName; + this.direction = direction; + this.distance = distance; + } + + public String getLineName() { + return lineName; + } + + public String getBaseStationName() { + return baseStationName; + } + + public String getAdditionalStationName() { + return additionalStationName; + } + + public Direction getDirection() { + return direction; + } + + public Integer getDistance() { + return distance; + } +} diff --git a/src/main/java/subway/entity/LineEntity.java b/src/main/java/subway/entity/LineEntity.java new file mode 100644 index 000000000..7326f9969 --- /dev/null +++ b/src/main/java/subway/entity/LineEntity.java @@ -0,0 +1,29 @@ +package subway.entity; + +public class LineEntity { + private Long id; + private String name; + private String color; + + public LineEntity(String name, String color) { + this(null, name, color); + } + + public LineEntity(Long id, String name, String color) { + this.id = id; + this.name = name; + this.color = color; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getColor() { + return color; + } +} diff --git a/src/main/java/subway/entity/SectionEntity.java b/src/main/java/subway/entity/SectionEntity.java new file mode 100644 index 000000000..542b96635 --- /dev/null +++ b/src/main/java/subway/entity/SectionEntity.java @@ -0,0 +1,51 @@ +package subway.entity; + +public class SectionEntity { + + private final Long id; + private final Long startStationId; + private final Long endStationId; + private final Integer distance; + private final Long lineId; + + public SectionEntity( + final Long startStationId, + final Long endStationId, + final Integer distance, + final Long lineId) { + this(null, startStationId, endStationId, distance, lineId); + } + + public SectionEntity( + final Long id, + final Long startStationId, + final Long endStationId, + final Integer distance, + final Long lineId) { + this.id = id; + this.startStationId = startStationId; + this.endStationId = endStationId; + this.distance = distance; + this.lineId = lineId; + } + + public Long getId() { + return id; + } + + public Long getStartStationId() { + return startStationId; + } + + public Long getEndStationId() { + return endStationId; + } + + public Integer getDistance() { + return distance; + } + + public Long getLineId() { + return lineId; + } +} diff --git a/src/main/java/subway/entity/StationEntity.java b/src/main/java/subway/entity/StationEntity.java new file mode 100644 index 000000000..5258ae70b --- /dev/null +++ b/src/main/java/subway/entity/StationEntity.java @@ -0,0 +1,29 @@ +package subway.entity; + +public class StationEntity { + private Long id; + private String name; + private Long lineId; + + public StationEntity(String name, Long lineId) { + this(null, name, lineId); + } + + public StationEntity(final Long id, final String name, final Long lineId) { + this.id = id; + this.name = name; + this.lineId = lineId; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public Long getLineId() { + return lineId; + } +} diff --git a/src/main/java/subway/exception/DistanceNotValidException.java b/src/main/java/subway/exception/DistanceNotValidException.java new file mode 100644 index 000000000..e6dbe4200 --- /dev/null +++ b/src/main/java/subway/exception/DistanceNotValidException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class DistanceNotValidException extends SubwayException { + + public DistanceNotValidException() { + super("๊ฑฐ๋ฆฌ ๊ฐ’์€ ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } +} diff --git a/src/main/java/subway/exception/GlobalExceptionHandler.java b/src/main/java/subway/exception/GlobalExceptionHandler.java new file mode 100644 index 000000000..9e29a88c1 --- /dev/null +++ b/src/main/java/subway/exception/GlobalExceptionHandler.java @@ -0,0 +1,51 @@ +package subway.exception; + +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import subway.dto.ExceptionResponse; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + private static final String DELIMITER = ", "; + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(final Exception e) { + logger.error("ERROR: ", e); + return ResponseEntity.internalServerError() + .body(new ExceptionResponse("์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")); + } + + @ExceptionHandler(SubwayException.class) + public ResponseEntity handleSubwayException(final SubwayException e) { + logger.warn(e.getMessage()); + return ResponseEntity.badRequest() + .body(new ExceptionResponse(e.getMessage())); + } + + @ExceptionHandler(LineNotFoundException.class) + public ResponseEntity handleLineNotFoundException(final LineNotFoundException e) { + logger.warn(e.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(new ExceptionResponse(e.getMessage())); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidException(final MethodArgumentNotValidException e) { + final String errorMessage = e.getFieldErrors().stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.joining(DELIMITER)); + logger.warn(errorMessage); + return ResponseEntity.badRequest() + .body(new ExceptionResponse(errorMessage)); + } +} diff --git a/src/main/java/subway/exception/InvalidSectionException.java b/src/main/java/subway/exception/InvalidSectionException.java new file mode 100644 index 000000000..65264edfc --- /dev/null +++ b/src/main/java/subway/exception/InvalidSectionException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class InvalidSectionException extends SubwayException { + + public InvalidSectionException(final String message) { + super(message); + } +} diff --git a/src/main/java/subway/exception/LineAlreadyExistsException.java b/src/main/java/subway/exception/LineAlreadyExistsException.java new file mode 100644 index 000000000..5c7e705e1 --- /dev/null +++ b/src/main/java/subway/exception/LineAlreadyExistsException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class LineAlreadyExistsException extends SubwayException { + + public LineAlreadyExistsException() { + super("๋…ธ์„ ์ด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."); + } +} diff --git a/src/main/java/subway/exception/LineNotEmptyException.java b/src/main/java/subway/exception/LineNotEmptyException.java new file mode 100644 index 000000000..d6b6c1a18 --- /dev/null +++ b/src/main/java/subway/exception/LineNotEmptyException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class LineNotEmptyException extends SubwayException { + + public LineNotEmptyException() { + super("๋…ธ์„ ์ด ๋น„์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } +} diff --git a/src/main/java/subway/exception/LineNotFoundException.java b/src/main/java/subway/exception/LineNotFoundException.java new file mode 100644 index 000000000..15b99d70f --- /dev/null +++ b/src/main/java/subway/exception/LineNotFoundException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class LineNotFoundException extends SubwayException { + + public LineNotFoundException() { + super("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } +} diff --git a/src/main/java/subway/exception/StationNotFoundException.java b/src/main/java/subway/exception/StationNotFoundException.java new file mode 100644 index 000000000..6b47f5f12 --- /dev/null +++ b/src/main/java/subway/exception/StationNotFoundException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class StationNotFoundException extends SubwayException { + + public StationNotFoundException() { + super("์—ญ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } +} diff --git a/src/main/java/subway/exception/SubwayException.java b/src/main/java/subway/exception/SubwayException.java new file mode 100644 index 000000000..6c6023e1b --- /dev/null +++ b/src/main/java/subway/exception/SubwayException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class SubwayException extends RuntimeException { + + public SubwayException(final String message) { + super(message); + } +} diff --git a/src/main/java/subway/repository/LineMapper.java b/src/main/java/subway/repository/LineMapper.java new file mode 100644 index 000000000..9a94ce1bc --- /dev/null +++ b/src/main/java/subway/repository/LineMapper.java @@ -0,0 +1,76 @@ +package subway.repository; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import org.springframework.stereotype.Component; +import subway.domain.Distance; +import subway.domain.Line; +import subway.domain.Section; +import subway.domain.Station; +import subway.entity.LineEntity; +import subway.entity.SectionEntity; +import subway.entity.StationEntity; + +@Component +public class LineMapper { + + public List toSectionEntities( + final Line line, + final Long lineId, + final List stationEntities + ) { + final Map stationNameByStationId = stationEntities.stream() + .collect(toMap(StationEntity::getName, StationEntity::getId)); + + return line.getSections().stream() + .filter(section -> Objects.isNull(section.getId())) + .map(section -> new SectionEntity( + stationNameByStationId.get(section.getStartName()), + stationNameByStationId.get(section.getEndName()), + section.getDistanceValue(), + lineId + )) + .collect(toList()); + } + + public List toStationEntities( + final Line line, + final Long lineId + ) { + return line.findAllStation().stream() + .map(station -> new StationEntity(station.getName(), lineId)) + .collect(toList()); + } + + public Line toLine( + final LineEntity lineEntity, + final List sectionEntities, + final List stationEntities + ) { + final Map stationIdByStationName = stationEntities.stream() + .collect(toMap(StationEntity::getId, StationEntity::getName)); + final List
sections = sectionEntities.stream() + .map(sectionEntity -> toSection(stationIdByStationName, sectionEntity)) + .collect(toList()); + + return new Line(lineEntity.getId(), lineEntity.getName(), lineEntity.getColor(), sections); + } + + private static Section toSection( + final Map stationIdByStationName, + final SectionEntity sectionEntity + ) { + return new Section( + sectionEntity.getId(), + new Station(sectionEntity.getStartStationId(), + stationIdByStationName.get(sectionEntity.getStartStationId())), + new Station(sectionEntity.getEndStationId(), + stationIdByStationName.get(sectionEntity.getEndStationId())), + new Distance(sectionEntity.getDistance()) + ); + } +} diff --git a/src/main/java/subway/repository/LineRepository.java b/src/main/java/subway/repository/LineRepository.java new file mode 100644 index 000000000..7f4fd4533 --- /dev/null +++ b/src/main/java/subway/repository/LineRepository.java @@ -0,0 +1,144 @@ +package subway.repository; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import org.springframework.stereotype.Repository; +import subway.dao.LineDao; +import subway.dao.SectionDao; +import subway.dao.StationDao; +import subway.domain.Line; +import subway.domain.Section; +import subway.domain.Station; +import subway.entity.LineEntity; +import subway.entity.SectionEntity; +import subway.entity.StationEntity; +import subway.exception.LineNotFoundException; + +@Repository +public class LineRepository { + + private final LineDao lineDao; + private final StationDao stationDao; + private final SectionDao sectionDao; + private final LineMapper lineMapper; + + public LineRepository( + final LineDao lineDao, + final StationDao stationDao, + final SectionDao sectionDao, + final LineMapper lineMapper + ) { + this.lineDao = lineDao; + this.stationDao = stationDao; + this.sectionDao = sectionDao; + this.lineMapper = lineMapper; + } + + public Line save(final Line line) { + if (Objects.isNull(line.getId())) { + return saveNewLine(line); + } + final Line savedLine = findById(line.getId()).orElseThrow(LineNotFoundException::new); + lineDao.update(new LineEntity(line.getId(), line.getName(), line.getColor())); + addNewStation(line); + addNewSection(line); + deleteRemovedSection(line, savedLine); + deleteRemovedStation(line, savedLine); + return findById(line.getId()).orElseThrow(LineNotFoundException::new); + } + + private Line saveNewLine(final Line line) { + final LineEntity lineEntity = lineDao.insert(new LineEntity(line.getName(), line.getColor())); + + final List stationEntities = lineMapper.toStationEntities(line, lineEntity.getId()); + stationDao.insertAll(stationEntities); + + final List savedStations = stationDao.findByLineId(lineEntity.getId()); + final List sectionEntities = lineMapper.toSectionEntities( + line, + lineEntity.getId(), + savedStations + ); + sectionDao.insertAll(sectionEntities); + + return findById(lineEntity.getId()) + .orElseThrow(LineNotFoundException::new); + } + + private void addNewStation(final Line line) { + line.findAllStation().stream() + .filter(station -> Objects.isNull(station.getId())) + .map(Station::getName) + .distinct() + .map(name -> new StationEntity(name, line.getId())) + .forEach(stationDao::insert); + } + + private void addNewSection(final Line line) { + final List stationEntities = stationDao.findByLineId(line.getId()); + final List sectionEntities = lineMapper.toSectionEntities(line, line.getId(), stationEntities); + sectionDao.insertAll(sectionEntities); + } + + private void deleteRemovedSection(final Line line, final Line savedLine) { + final Set
lineSections = new HashSet<>(line.getSections()); + final Set
savedLineSections = new HashSet<>(savedLine.getSections()); + savedLineSections.removeAll(lineSections); + + savedLineSections.stream() + .map(Section::getId) + .forEach(sectionDao::deleteById); + } + + private void deleteRemovedStation(final Line line, final Line savedLine) { + final Set lineStations = new HashSet<>(line.findAllStation()); + final Set savedLineStations = new HashSet<>(savedLine.findAllStation()); + savedLineStations.removeAll(lineStations); + + savedLineStations.stream() + .map(Station::getId) + .forEach(stationDao::deleteById); + } + + public List findAll() { + final List lineEntities = lineDao.findAll(); + final List sectionEntities = sectionDao.findAll(); + final List stationEntities = stationDao.findAll(); + final Map> lineIdBySectionEntities = sectionEntities.stream() + .collect(groupingBy(SectionEntity::getLineId)); + + return lineEntities.stream() + .map(lineEntity -> lineMapper.toLine( + lineEntity, + lineIdBySectionEntities.getOrDefault(lineEntity.getId(), new ArrayList<>()), + stationEntities) + ) + .collect(toList()); + } + + public Optional findIdByName(final String name) { + return lineDao.findByName(name).map(LineEntity::getId); + } + + public Optional findById(final Long id) { + return lineDao.findById(id).map(lineEntity -> { + final List sectionEntities = sectionDao.findByLineId(lineEntity.getId()); + final List stationEntities = stationDao.findAll(); + return lineMapper.toLine(lineEntity, sectionEntities, stationEntities); + }); + } + + public void deleteById(final Long id) { + sectionDao.deleteAllByLineId(id); + stationDao.deleteByLineId(id); + lineDao.deleteById(id); + } +} diff --git a/src/main/java/subway/ui/LineController.java b/src/main/java/subway/ui/LineController.java index 3a335ee14..ea5c67676 100644 --- a/src/main/java/subway/ui/LineController.java +++ b/src/main/java/subway/ui/LineController.java @@ -1,55 +1,60 @@ package subway.ui; +import java.net.URI; +import java.util.List; +import javax.validation.Valid; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import subway.application.LineService; -import subway.dto.LineRequest; +import subway.dto.LineAddRequest; import subway.dto.LineResponse; +import subway.dto.LineUpdateRequest; -import java.net.URI; -import java.sql.SQLException; -import java.util.List; - -@RestController @RequestMapping("/lines") +@RestController public class LineController { private final LineService lineService; - public LineController(LineService lineService) { + public LineController(final LineService lineService) { this.lineService = lineService; } @PostMapping - public ResponseEntity createLine(@RequestBody LineRequest lineRequest) { - LineResponse line = lineService.saveLine(lineRequest); - return ResponseEntity.created(URI.create("/lines/" + line.getId())).body(line); - } - - @GetMapping - public ResponseEntity> findAllLines() { - return ResponseEntity.ok(lineService.findLineResponses()); + public ResponseEntity add(@RequestBody @Valid final LineAddRequest request) { + final Long id = lineService.add(request); + return ResponseEntity.created(URI.create("/lines/" + id)).build(); } @GetMapping("/{id}") - public ResponseEntity findLineById(@PathVariable Long id) { - return ResponseEntity.ok(lineService.findLineResponseById(id)); + public ResponseEntity findById(@PathVariable final Long id) { + return ResponseEntity.ok(lineService.findById(id)); } - @PutMapping("/{id}") - public ResponseEntity updateLine(@PathVariable Long id, @RequestBody LineRequest lineUpdateRequest) { - lineService.updateLine(id, lineUpdateRequest); - return ResponseEntity.ok().build(); + @GetMapping + public ResponseEntity> findAll() { + return ResponseEntity.ok(lineService.findAll()); } - @DeleteMapping("/{id}") - public ResponseEntity deleteLine(@PathVariable Long id) { - lineService.deleteLineById(id); + @PatchMapping("/{id}") + public ResponseEntity update( + @PathVariable final Long id, + @RequestBody @Valid final LineUpdateRequest request + ) { + lineService.update(id, request); return ResponseEntity.noContent().build(); } - @ExceptionHandler(SQLException.class) - public ResponseEntity handleSQLException() { - return ResponseEntity.badRequest().build(); + @DeleteMapping("/{id}") + public ResponseEntity delete(@PathVariable final Long id) { + lineService.delete(id); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/subway/ui/StationController.java b/src/main/java/subway/ui/StationController.java index 5bf52a9a9..5d322d54b 100644 --- a/src/main/java/subway/ui/StationController.java +++ b/src/main/java/subway/ui/StationController.java @@ -1,54 +1,42 @@ package subway.ui; +import javax.validation.Valid; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import subway.dto.StationRequest; -import subway.dto.StationResponse; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import subway.application.StationService; +import subway.dto.StationDeleteRequest; +import subway.dto.StationInitialSaveRequest; +import subway.dto.StationSaveRequest; -import java.net.URI; -import java.sql.SQLException; -import java.util.List; - -@RestController @RequestMapping("/stations") +@RestController public class StationController { + private final StationService stationService; - public StationController(StationService stationService) { + public StationController(final StationService stationService) { this.stationService = stationService; } @PostMapping - public ResponseEntity createStation(@RequestBody StationRequest stationRequest) { - StationResponse station = stationService.saveStation(stationRequest); - return ResponseEntity.created(URI.create("/stations/" + station.getId())).body(station); - } - - @GetMapping - public ResponseEntity> showStations() { - return ResponseEntity.ok().body(stationService.findAllStationResponses()); - } - - @GetMapping("/{id}") - public ResponseEntity showStation(@PathVariable Long id) { - return ResponseEntity.ok().body(stationService.findStationResponseById(id)); - } - - @PutMapping("/{id}") - public ResponseEntity updateStation(@PathVariable Long id, @RequestBody StationRequest stationRequest) { - stationService.updateStation(id, stationRequest); + public ResponseEntity save(@RequestBody @Valid final StationSaveRequest request) { + stationService.save(request); return ResponseEntity.ok().build(); } - @DeleteMapping("/{id}") - public ResponseEntity deleteStation(@PathVariable Long id) { - stationService.deleteStationById(id); + @DeleteMapping + public ResponseEntity delete(@RequestBody @Valid final StationDeleteRequest request) { + stationService.delete(request); return ResponseEntity.noContent().build(); } - @ExceptionHandler(SQLException.class) - public ResponseEntity handleSQLException() { - return ResponseEntity.badRequest().build(); + @PostMapping("/init") + public ResponseEntity initialSave(@RequestBody @Valid final StationInitialSaveRequest request) { + stationService.initialSave(request); + return ResponseEntity.ok().build(); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 000000000..cdfe6e9a4 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,6 @@ +my: + datasource: + url: ${DB_URL:jdbc:h2:mem:test} + username: ${DB_USERNAME:sa} + password: ${DB_PASSWORD:} + driver-class-name: ${DB_DRIVER:org.h2.Driver} diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index fc6de5f5c..16c5da3ed 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,14 +1,29 @@ -create table if not exists STATION +CREATE TABLE IF NOT EXISTS LINE ( - id bigint auto_increment not null, - name varchar(255) not null unique, - primary key(id) + id BIGINT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) UNIQUE NOT NULL, + color VARCHAR(20) NOT NULL, + PRIMARY KEY (id) ); -create table if not exists LINE +CREATE TABLE IF NOT EXISTS STATION ( - id bigint auto_increment not null, - name varchar(255) not null unique, - color varchar(20) not null, - primary key(id) + id BIGINT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) NOT NULL, + line_id BIGINT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (line_id) REFERENCES LINE (id) +); + +CREATE TABLE IF NOT EXISTS SECTION +( + id BIGINT AUTO_INCREMENT NOT NULL, + start_station_id BIGINT NOT NULL, + end_station_id BIGINT NOT NULL, + distance INT NOT NULL, + line_id BIGINT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (start_station_id) REFERENCES STATION (id), + FOREIGN KEY (end_station_id) REFERENCES STATION (id), + FOREIGN KEY (line_id) REFERENCES LINE (id) ); diff --git a/src/test/java/subway/acceptance/LineAcceptanceTest.java b/src/test/java/subway/acceptance/LineAcceptanceTest.java new file mode 100644 index 000000000..fd0820e30 --- /dev/null +++ b/src/test/java/subway/acceptance/LineAcceptanceTest.java @@ -0,0 +1,175 @@ +package subway.acceptance; + +import static subway.common.steps.CommonSteps.๋น„์ •์ƒ_์š”์ฒญ; +import static subway.common.steps.CommonSteps.๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ; +import static subway.common.steps.CommonSteps.์š”์ฒญ_๊ฒฐ๊ณผ๊ฐ€_๋ฐ˜ํ™˜ํ•˜๋Š”_๋ฆฌ์†Œ์Šค์˜_์œ„์ฐจ๊ฐ€_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค; +import static subway.common.steps.CommonSteps.์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค; +import static subway.common.steps.CommonSteps.์ •์ƒ_์ƒ์„ฑ; +import static subway.common.steps.CommonSteps.์ •์ƒ_์š”์ฒญ; +import static subway.common.steps.CommonSteps.์ •์ƒ_์š”์ฒญ์ด์ง€๋งŒ_๋ฐ˜ํ™˜๊ฐ’_์—†์Œ; +import static subway.common.steps.LineSteps.๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค; +import static subway.common.steps.LineSteps.๋…ธ์„ _์‚ญ์ œ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ˆ˜์ •_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ •๋ณด; +import static subway.common.steps.LineSteps.๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค; +import static subway.common.steps.LineSteps.๋…ธ์„ _์กฐํšŒ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.์˜ค๋ฅธ์ชฝ; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import subway.common.AcceptanceTest; + +@SuppressWarnings("NonAsciiCharacters") +public class LineAcceptanceTest extends AcceptanceTest { + + @Nested + public class ๋…ธ์„ ์„_์ถ”๊ฐ€ํ• _๋•Œ { + + @Test + void ์ •์ƒ_์š”์ฒญ์˜_๊ฒฝ์šฐ_๋…ธ์„ ์ด_์ •์ƒ์ ์œผ๋กœ_์ถ”๊ฐ€๋œ๋‹ค() { + // given + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // expect + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์ƒ์„ฑ); + ์š”์ฒญ_๊ฒฐ๊ณผ๊ฐ€_๋ฐ˜ํ™˜ํ•˜๋Š”_๋ฆฌ์†Œ์Šค์˜_์œ„์ฐจ๊ฐ€_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ); + } + + @Test + void ์ด๋ฏธ_๊ฐ™์€_์ด๋ฆ„์œผ๋กœ_์ƒ์„ฑ๋œ_๋…ธ์„ ์ด_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + } + + @Nested + public class ๋…ธ์„ ์„_์กฐํšŒํ• _๋•Œ { + + @Test + void ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_์ƒํ–‰์ข…์ ์—ญ_๋ถ€ํ„ฐ_ํ•˜ํ–‰์ข…์ ์—ญ์œผ๋กœ_์ •๋ ฌ๋œ_๊ฒฐ๊ณผ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + final var ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); + + // when + final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด"); + } + + @Test + void ์กด์žฌํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + final var ์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ = String.valueOf(Long.MAX_VALUE); + + // when + final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ); + } + } + + @Nested + public class ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ• _๋•Œ { + + @Test + void ์ƒํ–‰์ข…์ ์—ญ_๋ถ€ํ„ฐ_ํ•˜ํ–‰์ข…์ ์—ญ์œผ๋กœ_์ •๋ ฌ๋œ_๊ฒฐ๊ณผ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ", ์˜ค๋ฅธ์ชฝ, 5); + + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๊ณ ๋™"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", 3); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „", ์˜ค๋ฅธ์ชฝ, 7); + + // when + final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์กฐํšŒ_๊ฒฐ๊ณผ, + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ"), + ๋…ธ์„ _์ •๋ณด("9ํ˜ธ์„ ", "๊ณ ๋™", "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „") + ); + } + } + + @Nested + public class ๋…ธ์„ ์„_์ˆ˜์ •ํ• _๋•Œ { + + @Test + void ๋…ธ์„ _๋ฒˆํ˜ธ์™€_์ˆ˜์ •ํ• _๋‚ด์šฉ์„_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { + // given + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final String ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); + + // when + final var ์ˆ˜์ •_๊ฒฐ๊ณผ = ๋…ธ์„ _์ˆ˜์ •_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ, "1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์ˆ˜์ •_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ์ด์ง€๋งŒ_๋ฐ˜ํ™˜๊ฐ’_์—†์Œ); + final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ); + ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + } + + @Test + void ์กด์žฌํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + final var ์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ = String.valueOf(Long.MAX_VALUE); + + // when + final var ์ˆ˜์ •_๊ฒฐ๊ณผ = ๋…ธ์„ _์ˆ˜์ •_์š”์ฒญ(์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ, "1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์ˆ˜์ •_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ); + } + } + + @Nested + public class ๋…ธ์„ ์„_์‚ญ์ œํ• _๋•Œ { + + @Test + void ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { + // given + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); + + // when + final var ์‚ญ์ œ_๊ฒฐ๊ณผ = ๋…ธ์„ _์‚ญ์ œ_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์‚ญ์ œ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ์ด์ง€๋งŒ_๋ฐ˜ํ™˜๊ฐ’_์—†์Œ); + final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ); + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ); + } + + @Test + void ์กด์žฌํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + final var ์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ = String.valueOf(Long.MAX_VALUE); + + // when + final var ์‚ญ์ œ_๊ฒฐ๊ณผ = ๋…ธ์„ _์‚ญ์ œ_์š”์ฒญ(์กด์žฌ_ํ•˜์ง€_์•Š๋Š”_๋…ธ์„ _๋ฒˆํ˜ธ); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์‚ญ์ œ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ); + } + } +} diff --git a/src/test/java/subway/acceptance/StationAcceptanceTest.java b/src/test/java/subway/acceptance/StationAcceptanceTest.java new file mode 100644 index 000000000..6c9f7fd8b --- /dev/null +++ b/src/test/java/subway/acceptance/StationAcceptanceTest.java @@ -0,0 +1,184 @@ +package subway.acceptance; + +import static subway.common.steps.CommonSteps.๋น„์ •์ƒ_์š”์ฒญ; +import static subway.common.steps.CommonSteps.์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค; +import static subway.common.steps.CommonSteps.์ •์ƒ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ •๋ณด; +import static subway.common.steps.SectionSteps.๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.์˜ค๋ฅธ์ชฝ; +import static subway.common.steps.SectionSteps.์™ผ์ชฝ; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import subway.common.AcceptanceTest; + +@SuppressWarnings("NonAsciiCharacters") +public class StationAcceptanceTest extends AcceptanceTest { + + @Nested + public class ๋นˆ_๋…ธ์„ ์ธ_๊ฒฝ์šฐ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ์„_ํ†ตํ•ด_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค { + + @Test + void ์ด_๋•Œ_์ •์ƒ_์š”์ฒญ์˜_๊ฒฝ์šฐ_์—ญ_๋‘๊ฐœ๊ฐ€_์ •์ƒ์ ์œผ๋กœ_์ถ”๊ฐ€๋œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + + // expect + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); + ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์ „์ฒด_๋…ธ์„ _์ •๋ณด, + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") + ); + } + + @Test + void ์ด_๋•Œ_๋…ธ์„ ์—_์—ญ์ด_์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + } + + @Nested + public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { + + @Test + void ๊ธฐ์ค€์—ญ์ด_์กด์žฌํ•œ๋‹ค๋ฉด_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ์„_ํ†ตํ•ด_์—ญ์„_์ถ”๊ฐ€ํ• _์ˆ˜_์žˆ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); + + // when + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค์ƒˆ๋‚ด", ์™ผ์ชฝ, 2); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); + ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์ „์ฒด_๋…ธ์„ _์ •๋ณด, + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ") + ); + } + + @Test + void ์ „์ฒด_๋…ธ์„ ์—_์ƒ์„ฑํ• _๊ตฌ๊ฐ„์ด_์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + + @Test + void ๋“ฑ๋กํ• _์—ญ์ด_๊ฐ™์€_๋…ธ์„ ์—๋Š”_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ", ์˜ค๋ฅธ์ชฝ, 2); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค", ์˜ค๋ฅธ์ชฝ, 2); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + + @Test + void ๊ธฐ์ค€์—ญ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค", ์˜ค๋ฅธ์ชฝ, 2); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + + @Test + void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์ถ”๊ฐ€ํ•˜๋Š”_๊ฒฝ์šฐ_๊ตฌ๊ฐ„_์‚ฌ์ด์˜_๊ธธ์ด๋ณด๋‹ค_์ถ”๊ฐ€ํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ฐ™๊ฑฐ๋‚˜_๊ธด๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค์ƒˆ๋‚ด", ์™ผ์ชฝ, 5); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + } + + @Nested + public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์‚ญ์ œํ• _๋•Œ { + + @Test + void ํ•ด๋‹น_๋…ธ์„ ์—_์—ญ์ด_๋‘๊ฐœ_๋ฐ–์—_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_๋ชจ๋“ _์—ญ์ด_์‚ญ์ œ๋œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); + + // when + ๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); + ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์ „์ฒด_๋…ธ์„ _์ •๋ณด, + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก") + ); + } + + @Test + void ์ •์ƒ_์š”์ฒญ์ธ_๊ฒฝ์šฐ_์—ญ์ด_์‚ญ์ œ๋œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค์ƒˆ๋‚ด", ์™ผ์ชฝ, 2); + + // when + ๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); + ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์ „์ฒด_๋…ธ์„ _์ •๋ณด, + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") + ); + } + + @Test + void ์กด์žฌํ•˜์ง€_์•Š๋Š”_์—ญ์€_์‚ญ์ œ_์š”์ฒญํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { + // given + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); + + // when + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ("2ํ˜ธ์„ ", "์‚ฌ๋‹น"); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); + } + } +} diff --git a/src/test/java/subway/application/LineServiceTest.java b/src/test/java/subway/application/LineServiceTest.java new file mode 100644 index 000000000..a0e8e2cfd --- /dev/null +++ b/src/test/java/subway/application/LineServiceTest.java @@ -0,0 +1,159 @@ +package subway.application; + +import static java.lang.Long.MAX_VALUE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; +import subway.domain.Line; +import subway.domain.Section; +import subway.dto.LineAddRequest; +import subway.dto.LineResponse; +import subway.dto.LineUpdateRequest; +import subway.exception.LineAlreadyExistsException; +import subway.exception.LineNotFoundException; +import subway.repository.LineRepository; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@Transactional +@SpringBootTest +class LineServiceTest { + + @Autowired + private LineService lineService; + + @Autowired + private LineRepository lineRepository; + + @Test + void ๋ผ์ธ์„_์ €์žฅํ•œ๋‹ค() { + // given + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + + // when + final Long id = lineService.add(request); + + // then + assertAll( + () -> assertThat(lineRepository.findAll()).hasSize(1), + () -> assertThat(id).isPositive() + ); + } + + @Test + void ๋ผ์ธ์„_์ €์žฅํ• _๋•Œ_์ด๋ฏธ_๋ผ์ธ์ด_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + lineService.add(request); + + // expect + assertThatThrownBy(() -> lineService.add(request)) + .isInstanceOf(LineAlreadyExistsException.class) + .hasMessage("๋…ธ์„ ์ด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."); + } + + @Test + void ๋ผ์ธid๋ฅผ_๋ฐ›์•„์„œ_๋ผ์ธ์„_์‚ญ์ œํ•œ๋‹ค() { + // given + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + final Long id = lineService.add(request); + + // when + lineService.delete(id); + + // then + assertThat(lineRepository.findAll()).isEmpty(); + } + + @Test + void ๋ผ์ธid๋ฅผ_๋ฐ›์•„์„œ_๋ผ์ธ์„_์‚ญ์ œํ• _๋•Œ_๋ผ์ธ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // expect + assertThatThrownBy(() -> lineService.delete(MAX_VALUE)) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋ผ์ธ์„_์ˆ˜์ •ํ•œ๋‹ค() { + // given + final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED")); + final LineUpdateRequest request = new LineUpdateRequest("2ํ˜ธ์„ ", "BLACK"); + + // when + lineService.update(id, request); + + // then + final Line result = lineRepository.findAll().get(0); + assertAll( + () -> assertThat(result.getName()).isEqualTo("2ํ˜ธ์„ "), + () -> assertThat(result.getColor()).isEqualTo("BLACK") + ); + } + + @Test + void ๋ผ์ธid๋ฅผ_๋ฐ›์•„์„œ_๋ผ์ธ์„_์ˆ˜์ •ํ• _๋•Œ_๋ผ์ธ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final LineUpdateRequest request = new LineUpdateRequest("2ํ˜ธ์„ ", "BLACK"); + + // expect + assertThatThrownBy(() -> lineService.update(MAX_VALUE, request)) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋ผ์ธid๋กœ_๋ผ์ธ์„_์กฐํšŒํ•œ๋‹ค() { + // given + final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED")); + + // when + final LineResponse result = lineService.findById(id); + + // then + assertAll( + () -> assertThat(result.getName()).isEqualTo("1ํ˜ธ์„ "), + () -> assertThat(result.getColor()).isEqualTo("RED"), + () -> assertThat(result.getStations()).isEmpty() + ); + } + + @Test + void ๋ผ์ธid๋กœ_๋ผ์ธ์„_์กฐํšŒํ• _๋•Œ_๋ผ์ธ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // expect + assertThatThrownBy(() -> lineService.findById(MAX_VALUE)) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋ผ์ธ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 3), + new Section("B", "Y", 2) + ))); + + // when + final List result = lineService.findAll(); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo(List.of( + new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B", "C", "D", "E")), + new LineResponse("2ํ˜ธ์„ ", "BLUE", List.of("Z", "B", "Y")) + )); + } +} diff --git a/src/test/java/subway/application/StationServiceTest.java b/src/test/java/subway/application/StationServiceTest.java new file mode 100644 index 000000000..e66a627d5 --- /dev/null +++ b/src/test/java/subway/application/StationServiceTest.java @@ -0,0 +1,104 @@ +package subway.application; + +import static org.assertj.core.api.Assertions.assertThat; +import static subway.domain.Direction.RIGHT; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; +import subway.domain.Line; +import subway.domain.Section; +import subway.dto.StationDeleteRequest; +import subway.dto.StationInitialSaveRequest; +import subway.dto.StationSaveRequest; +import subway.repository.LineRepository; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@Transactional +@SpringBootTest +public class StationServiceTest { + + @Autowired + private StationService stationService; + + @Autowired + private LineRepository lineRepository; + + @Test + void ์—ญ์„_๋“ฑ๋กํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 2), + new Section("B", "Y", 3) + ))); + final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", RIGHT, 3); + + // when + stationService.save(request); + + // then + assertThat(lineRepository.findAll()).flatExtracting(Line::getSections) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 2), + new Section("B", "C", 3), + new Section("Z", "B", 2), + new Section("B", "Y", 3) + )); + } + + @Test + void ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2), + new Section("B", "C", 3) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 2), + new Section("B", "Y", 3) + ))); + final StationDeleteRequest request = new StationDeleteRequest("1ํ˜ธ์„ ", "B"); + + // when + stationService.delete(request); + + // then + assertThat(lineRepository.findAll()).flatExtracting(Line::getSections) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "C", 5), + new Section("Z", "B", 2), + new Section("B", "Y", 3) + )); + } + + @Test + void ๋ผ์ธ์ด_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_์—ญ์„_๋“ฑ๋กํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList())); + final StationInitialSaveRequest request = new StationInitialSaveRequest("1ํ˜ธ์„ ", "A", "B", 3); + + // when + stationService.initialSave(request); + + // then + assertThat(lineRepository.findAll()).flatExtracting(Line::getSections) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 3) + )); + } +} diff --git a/src/test/java/subway/common/AcceptanceTest.java b/src/test/java/subway/common/AcceptanceTest.java new file mode 100644 index 000000000..0bbac698f --- /dev/null +++ b/src/test/java/subway/common/AcceptanceTest.java @@ -0,0 +1,4 @@ +package subway.common; + +public abstract class AcceptanceTest extends IntegrationTest { +} diff --git a/src/test/java/subway/common/IntegrationTest.java b/src/test/java/subway/common/IntegrationTest.java new file mode 100644 index 000000000..e16b9290b --- /dev/null +++ b/src/test/java/subway/common/IntegrationTest.java @@ -0,0 +1,24 @@ +package subway.common; + +import io.restassured.RestAssured; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.context.jdbc.Sql; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@Sql(value = "/deleteAll.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public abstract class IntegrationTest { + + @LocalServerPort + int port; + + @BeforeEach + public void setUp() { + RestAssured.port = port; + } +} diff --git a/src/test/java/subway/common/steps/CommonSteps.java b/src/test/java/subway/common/steps/CommonSteps.java new file mode 100644 index 000000000..20eaae094 --- /dev/null +++ b/src/test/java/subway/common/steps/CommonSteps.java @@ -0,0 +1,25 @@ +package subway.common.steps; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.springframework.http.HttpStatus; + +@SuppressWarnings("NonAsciiCharacters") +public class CommonSteps { + + public static HttpStatus ์ •์ƒ_์š”์ฒญ = HttpStatus.OK; + public static HttpStatus ์ •์ƒ_์ƒ์„ฑ = HttpStatus.CREATED; + public static HttpStatus ์ •์ƒ_์š”์ฒญ์ด์ง€๋งŒ_๋ฐ˜ํ™˜๊ฐ’_์—†์Œ = HttpStatus.NO_CONTENT; + public static HttpStatus ๋น„์ •์ƒ_์š”์ฒญ = HttpStatus.BAD_REQUEST; + public static HttpStatus ๋น„์ •์ƒ_์š”์ฒญ_์š”์ฒญํ•œ_๋ฆฌ์†Œ์Šค_์ฐพ์„_์ˆ˜_์—†์Œ = HttpStatus.NOT_FOUND; + + public static void ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ, final HttpStatus ์ƒํƒœ) { + assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.statusCode()).isEqualTo(์ƒํƒœ.value()); + } + + public static void ์š”์ฒญ_๊ฒฐ๊ณผ๊ฐ€_๋ฐ˜ํ™˜ํ•˜๋Š”_๋ฆฌ์†Œ์Šค์˜_์œ„์ฐจ๊ฐ€_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ) { + assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.header("Location")).isNotBlank(); + } +} diff --git a/src/test/java/subway/common/steps/LineSteps.java b/src/test/java/subway/common/steps/LineSteps.java new file mode 100644 index 000000000..ad1b63738 --- /dev/null +++ b/src/test/java/subway/common/steps/LineSteps.java @@ -0,0 +1,101 @@ +package subway.common.steps; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.http.MediaType; +import subway.dto.LineAddRequest; +import subway.dto.LineResponse; +import subway.dto.LineUpdateRequest; + +@SuppressWarnings("NonAsciiCharacters") +public class LineSteps { + + public static ExtractableResponse ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ) { + final LineAddRequest request = new LineAddRequest(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/lines") + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(final String ๋…ธ์„ _๋ฒˆํ˜ธ) { + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/lines/" + ๋…ธ์„ _๋ฒˆํ˜ธ) + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ() { + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/lines") + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๋…ธ์„ _์ˆ˜์ •_์š”์ฒญ(final String ๋…ธ์„ _๋ฒˆํ˜ธ, final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ) { + final LineUpdateRequest request = new LineUpdateRequest(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().patch("/lines/" + ๋…ธ์„ _๋ฒˆํ˜ธ) + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๋…ธ์„ _์‚ญ์ œ_์š”์ฒญ(final String ๋…ธ์„ _๋ฒˆํ˜ธ) { + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().delete("/lines/" + ๋…ธ์„ _๋ฒˆํ˜ธ) + .then().log().all() + .extract(); + } + + public static String ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ) { + final int index = 2; + return ์š”์ฒญ_๊ฒฐ๊ณผ.header("Location").split("/")[index]; + } + + public static void ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ, + final String ๋…ธ์„ ๋ช…, + final String ์ƒ‰์ƒ, + final String... ์—ญ + ) { + final List ์—ญ_๋ชจ์Œ = Arrays.stream(์—ญ).collect(Collectors.toList()); + assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.jsonPath().getObject(".", LineResponse.class)) + .usingRecursiveComparison() + .isEqualTo(new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์—ญ_๋ชจ์Œ)); + } + + public static LineResponse ๋…ธ์„ _์ •๋ณด(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ, final String... ์—ญ) { + final List ์—ญ_๋ชจ์Œ = Arrays.stream(์—ญ).collect(Collectors.toList()); + return new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์—ญ_๋ชจ์Œ); + } + + public static void ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ, + final LineResponse... ๋…ธ์„ _์ •๋ณด + ) { + final List ์ „์ฒด_๋…ธ์„ _์ •๋ณด = Arrays.stream(๋…ธ์„ _์ •๋ณด).collect(Collectors.toList()); + assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.jsonPath().getList(".", LineResponse.class)) + .usingRecursiveComparison() + .isEqualTo(์ „์ฒด_๋…ธ์„ _์ •๋ณด); + } +} diff --git a/src/test/java/subway/common/steps/SectionSteps.java b/src/test/java/subway/common/steps/SectionSteps.java new file mode 100644 index 000000000..8511f0db9 --- /dev/null +++ b/src/test/java/subway/common/steps/SectionSteps.java @@ -0,0 +1,69 @@ +package subway.common.steps; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.springframework.http.MediaType; +import subway.domain.Direction; +import subway.domain.Section; +import subway.dto.StationDeleteRequest; +import subway.dto.StationInitialSaveRequest; +import subway.dto.StationSaveRequest; + +@SuppressWarnings("NonAsciiCharacters") +public class SectionSteps { + + public static final Direction ์™ผ์ชฝ = Direction.LEFT; + public static final Direction ์˜ค๋ฅธ์ชฝ = Direction.RIGHT; + + public static ExtractableResponse ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ( + final String ๋…ธ์„ ๋ช…, + final String ์ƒํ–‰์ข…์ ์—ญ, + final String ํ•˜ํ–‰์ข…์ ์—ญ, + final int ๊ฑฐ๋ฆฌ + ) { + final StationInitialSaveRequest request = new StationInitialSaveRequest(๋…ธ์„ ๋ช…, ์ƒํ–‰์ข…์ ์—ญ, ํ•˜ํ–‰์ข…์ ์—ญ, ๊ฑฐ๋ฆฌ); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/stations/init") + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ( + final String ๋…ธ์„ ๋ช…, + final String ๊ธฐ์ค€์—ญ, + final String ์ถ”๊ฐ€์—ญ, + final Direction ๋ฐฉํ–ฅ, + final int ๊ฑฐ๋ฆฌ + ) { + final StationSaveRequest request = new StationSaveRequest(๋…ธ์„ ๋ช…, ๊ธฐ์ค€์—ญ, ์ถ”๊ฐ€์—ญ, ๋ฐฉํ–ฅ, ๊ฑฐ๋ฆฌ); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/stations") + .then().log().all() + .extract(); + } + + public static ExtractableResponse ๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ(final String ๋…ธ์„ ๋ช…, final String ์‚ญ์ œ์—ญ) { + final StationDeleteRequest request = new StationDeleteRequest(๋…ธ์„ ๋ช…, ์‚ญ์ œ์—ญ); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().delete("/stations") + .then().log().all() + .extract(); + } + + public static Section ๊ตฌ๊ฐ„(final String ์ƒํ–‰์—ญ, final String ํ•˜ํ–‰์—ญ, final int ๊ฑฐ๋ฆฌ) { + return new Section(์ƒํ–‰์—ญ, ํ•˜ํ–‰์—ญ, ๊ฑฐ๋ฆฌ); + } +} diff --git a/src/test/java/subway/dao/LineDaoTest.java b/src/test/java/subway/dao/LineDaoTest.java new file mode 100644 index 000000000..8be9b7eb6 --- /dev/null +++ b/src/test/java/subway/dao/LineDaoTest.java @@ -0,0 +1,119 @@ +package subway.dao; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.jdbc.core.JdbcTemplate; +import subway.entity.LineEntity; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@JdbcTest +class LineDaoTest { + + @Autowired + private JdbcTemplate jdbcTemplate; + + private LineDao lineDao; + + @BeforeEach + void setUp() { + lineDao = new LineDao(jdbcTemplate); + } + + @Test + void ๋…ธ์„ ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + + // when + final LineEntity result = lineDao.insert(line); + + // then + final LineEntity findLine = lineDao.findById(result.getId()).get(); + assertAll( + () -> assertThat(findLine.getName()).isEqualTo(result.getName()), + () -> assertThat(findLine.getColor()).isEqualTo(result.getColor()) + ); + } + + @Test + void ๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { + // given + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity insertLine = lineDao.insert(line); + final LineEntity newLine = new LineEntity(insertLine.getId(), "2ํ˜ธ์„ ", "BLUE"); + + // when + lineDao.update(newLine); + + // then + final LineEntity result = lineDao.findById(newLine.getId()).get(); + assertAll( + () -> assertThat(result.getName()).isEqualTo(newLine.getName()), + () -> assertThat(result.getColor()).isEqualTo(newLine.getColor()) + ); + } + + @Test + void ๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { + // given + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity insertLine = lineDao.insert(line); + + // when + lineDao.deleteById(insertLine.getId()); + + // then + assertThat(lineDao.findAll()).hasSize(0); + } + + @Test + void ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line1 = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line2 = new LineEntity("2ํ˜ธ์„ ", "BLUE"); + final LineEntity insertLine1 = lineDao.insert(line1); + final LineEntity insertLine2 = lineDao.insert(line2); + + // when + final List result = lineDao.findAll(); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo(List.of(insertLine1, insertLine2)); + } + + @Test + void ๋…ธ์„ ์„_id๋กœ_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity insertLine = lineDao.insert(line); + + // when + final Optional result = lineDao.findById(insertLine.getId()); + + // then + assertThat(result).isPresent(); + } + + @Test + void ๋…ธ์„ ์„_์ด๋ฆ„์œผ๋กœ_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + lineDao.insert(line); + + // when + final Optional result = lineDao.findByName("1ํ˜ธ์„ "); + + // then + assertThat(result).isPresent(); + } +} diff --git a/src/test/java/subway/dao/SectionDaoTest.java b/src/test/java/subway/dao/SectionDaoTest.java new file mode 100644 index 000000000..11558233a --- /dev/null +++ b/src/test/java/subway/dao/SectionDaoTest.java @@ -0,0 +1,140 @@ +package subway.dao; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.jdbc.core.JdbcTemplate; +import subway.entity.LineEntity; +import subway.entity.SectionEntity; +import subway.entity.StationEntity; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@JdbcTest +public class SectionDaoTest { + + @Autowired + private JdbcTemplate jdbcTemplate; + + private SectionDao sectionDao; + private LineDao lineDao; + private StationDao stationDao; + + @BeforeEach + void setUp() { + sectionDao = new SectionDao(jdbcTemplate); + lineDao = new LineDao(jdbcTemplate); + stationDao = new StationDao(jdbcTemplate); + } + + @Test + void ๊ตฌ๊ฐ„์„_์ „์ฒด_์ €์žฅํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); + final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); + final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); + + final List sections = List.of( + new SectionEntity(station1.getId(), station2.getId(), 3, line.getId()), + new SectionEntity(station2.getId(), station3.getId(), 5, line.getId()) + ); + + // when + sectionDao.insertAll(sections); + + // then + final List result = sectionDao.findAll(); + assertThat(result).usingRecursiveComparison().ignoringFields("id").isEqualTo(sections); + } + + @Test + void ๊ตฌ๊ฐ„์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); + final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); + final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); + + final List sections = List.of( + new SectionEntity(station1.getId(), station2.getId(), 3, line.getId()), + new SectionEntity(station2.getId(), station3.getId(), 5, line.getId()) + ); + sectionDao.insertAll(sections); + + // when + final List result = sectionDao.findAll(); + + // then + assertThat(result).usingRecursiveComparison().ignoringFields("id").isEqualTo(sections); + } + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๋…ธ์„ _id์—_ํ•ด๋‹นํ•˜๋Š”_๊ตฌ๊ฐ„์„_์ „์ฒด_์‚ญ์ œํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); + final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); + final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); + + final List sections = List.of( + new SectionEntity(station1.getId(), station2.getId(), 3, line.getId()), + new SectionEntity(station2.getId(), station3.getId(), 5, line.getId()) + ); + sectionDao.insertAll(sections); + + // when + sectionDao.deleteAllByLineId(line.getId()); + + // then + assertThat(sectionDao.findAll()).hasSize(0); + } + + @Test + void ๋ผ์ธ_id๋ฅผ_๋ฐ›์•„_๊ตฌ๊ฐ„์„_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); + final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); + final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); + + final List sections = List.of( + new SectionEntity(station1.getId(), station2.getId(), 3, line.getId()), + new SectionEntity(station2.getId(), station3.getId(), 5, line.getId()) + ); + sectionDao.insertAll(sections); + + // when + final List result = sectionDao.findByLineId(line.getId()); + + // then + assertThat(result).usingRecursiveComparison().ignoringFields("id").isEqualTo(sections); + } + + @Test + void ๊ตฌ๊ฐ„_id๋ฅผ_๋ฐ›์•„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); + final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); + + final List sections = List.of( + new SectionEntity(station1.getId(), station2.getId(), 3, line.getId()) + ); + sectionDao.insertAll(sections); + final SectionEntity sectionEntity = sectionDao.findByLineId(line.getId()).get(0); + + // when + sectionDao.deleteById(sectionEntity.getId()); + + // then + final List result = sectionDao.findAll(); + assertThat(result).isEmpty(); + } +} diff --git a/src/test/java/subway/dao/StationDaoTest.java b/src/test/java/subway/dao/StationDaoTest.java new file mode 100644 index 000000000..9177687cc --- /dev/null +++ b/src/test/java/subway/dao/StationDaoTest.java @@ -0,0 +1,132 @@ +package subway.dao; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.jdbc.core.JdbcTemplate; +import subway.entity.LineEntity; +import subway.entity.StationEntity; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@JdbcTest +class StationDaoTest { + + @Autowired + private JdbcTemplate jdbcTemplate; + + private LineDao lineDao; + private StationDao stationDao; + + @BeforeEach + void setUp() { + lineDao = new LineDao(jdbcTemplate); + stationDao = new StationDao(jdbcTemplate); + } + + @Test + void ์—ญ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + stationDao.insertAll(List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + )); + + // when + final List result = stationDao.findAll(); + + // then + assertThat(result).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + )); + } + + @Test + void ๋…ธ์„ id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_์—ญ์„_์ „์ฒด_์‚ญ์ œํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + stationDao.insertAll(List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + )); + + // when + stationDao.deleteByLineId(line.getId()); + + // then + assertThat(stationDao.findAll()).hasSize(0); + } + + @Test + void ์—ญ์„_๋ชจ๋‘_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final List stations = List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + ); + + // when + stationDao.insertAll(stations); + + // then + assertThat(stationDao.findAll()).hasSize(2); + } + + @Test + void ์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity station = new StationEntity("B", line.getId()); + + // when + final StationEntity result = stationDao.insert(station); + + // then + assertAll( + () -> assertThat(result.getId()).isPositive(), + () -> assertThat(stationDao.findAll()).hasSize(1) + ); + } + + @Test + void ๋…ธ์„ _id๋ฅผ_๋ฐ›์•„_์—ญ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + stationDao.insertAll(List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + )); + + // when + final List result = stationDao.findByLineId(line.getId()); + + // then + assertThat(result).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( + new StationEntity("A", line.getId()), + new StationEntity("B", line.getId()) + )); + } + + @Test + void id๋ฅผ_๋ฐ›์•„_์—ญ์„_์‚ญ์ œํ•œ๋‹ค() { + // given + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final StationEntity stationEntity = stationDao.insert(new StationEntity("A", line.getId())); + + // when + stationDao.deleteById(stationEntity.getId()); + + // then + assertThat(stationDao.findAll()).isEmpty(); + } +} diff --git a/src/test/java/subway/domain/DirectionTest.java b/src/test/java/subway/domain/DirectionTest.java new file mode 100644 index 000000000..4e87a0989 --- /dev/null +++ b/src/test/java/subway/domain/DirectionTest.java @@ -0,0 +1,42 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class DirectionTest { + + @CsvSource({"LEFT, RIGHT", "RIGHT, LEFT"}) + @ParameterizedTest(name = "{0}์˜ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์€ {1}์ด๋‹ค.") + void ๋ฐ˜๋Œ€_๋ฐฉํ–ฅ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค(final Direction sut, final Direction result) { + // expect + assertThat(sut.flip()).isEqualTo(result); + } + + @Test + void ๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + List
sections = new ArrayList<>(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + Direction.LEFT.addStation(sections, new Station("B"), new Station("D"), new Distance(2)); + + // then + assertThat(sections).contains( + new Section("A", "D", 3), + new Section("D", "B", 2), + new Section("B", "C", 5) + ); + } +} diff --git a/src/test/java/subway/domain/DistanceTest.java b/src/test/java/subway/domain/DistanceTest.java new file mode 100644 index 000000000..030be513a --- /dev/null +++ b/src/test/java/subway/domain/DistanceTest.java @@ -0,0 +1,72 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import subway.exception.DistanceNotValidException; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class DistanceTest { + + @ParameterizedTest(name = "์–‘์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ์ž…๋ ฅ๋ฐ›๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ž…๋ ฅ: {0}") + @ValueSource(ints = {0, -1}) + void ์–‘์ˆ˜๊ฐ€_์•„๋‹Œ_๊ฐ’์„_์ž…๋ ฅ๋ฐ›๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค(final int value) { + // expect + assertThatThrownBy(() -> new Distance(value)) + .isInstanceOf(DistanceNotValidException.class) + .hasMessage("๊ฑฐ๋ฆฌ ๊ฐ’์€ ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + + @Test + void ์–‘์ˆ˜๋ฅผ_์ž…๋ ฅ๋ฐ›๋Š”_๊ฒฝ์šฐ_์ •์ƒ์ ์œผ๋กœ_์ƒ์„ฑ๋œ๋‹ค() { + // given + int value = 1; + + // when + final Distance distance = new Distance(value); + + // then + assertThat(distance.getValue()).isEqualTo(1); + } + + @ParameterizedTest(name = "3๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค. ์ž…๋ ฅ: {0}, ๊ฒฐ๊ณผ: {1}") + @CsvSource({"2, false", "3, true", "4, true"}) + void ์ž์‹ ์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_ํฌ๊ฑฐ๋‚˜_๊ฐ™์€์ง€_ํ™•์ธํ•œ๋‹ค(final int value, final boolean result) { + // given + final Distance distance = new Distance(3); + + // expect + assertThat(distance.moreThanOrEqual(new Distance(value))).isEqualTo(result); + } + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๋ฅผ_๋บ€_๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Distance distance = new Distance(5); + + // when + final Distance result = distance.subtract(new Distance(2)); + + // then + assertThat(result).isEqualTo(new Distance(3)); + } + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๋ฅผ_๋”ํ•œ_๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Distance distance = new Distance(5); + + // when + final Distance result = distance.add(new Distance(2)); + + // then + assertThat(result).isEqualTo(new Distance(7)); + } +} diff --git a/src/test/java/subway/domain/LineTest.java b/src/test/java/subway/domain/LineTest.java new file mode 100644 index 000000000..dce3b1366 --- /dev/null +++ b/src/test/java/subway/domain/LineTest.java @@ -0,0 +1,337 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; +import static subway.domain.Direction.LEFT; +import static subway.domain.Direction.RIGHT; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import subway.exception.InvalidSectionException; +import subway.exception.LineNotEmptyException; +import subway.exception.StationNotFoundException; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class LineTest { + + @CsvSource({"A, B, true", "C, D, false", "B, A, true"}) + @ParameterizedTest(name = "๋…ธ์„  ์—ฐ๊ฒฐ ์ƒํƒœ๊ฐ€ [A-B-C]์ผ ๋•Œ {0}๊ณผ {1}๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๊ฒฐ๊ณผ: {2}") + void ์ž…๋ ฅ_๋ฐ›์€_๋‘_์—ญ์ด_์—ฐ๊ฒฐ๋˜์–ด_์žˆ๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(final String start, final String end, final boolean result) { + // given + List
sections = List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + ); + final Line line = new Line("2ํ˜ธ์„ ", "RED", sections); + + // expect + assertThat(line.containsAll(new Station(start), new Station(end))).isEqualTo(result); + } + + @Test + void ๋…ธ์„ ์—_๊ธฐ์ค€_์—ญ์ด_์—†์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // expect + assertThatThrownBy(() -> line.add(new Station("D"), new Station("C"), new Distance(3), LEFT)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("๊ธฐ์ค€์—ญ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋…ธ์„ ์—_๋“ฑ๋กํ• _์—ญ์ด_์žˆ์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // expect + assertThatThrownBy(() -> line.add(new Station("C"), new Station("A"), new Distance(3), LEFT)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("๋“ฑ๋กํ•  ์—ญ์ด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."); + } + + @ValueSource(ints = {5, 6}) + @ParameterizedTest(name = "{displayName} ์ž…๋ ฅ: {0}") + void ํ•˜ํ–‰๋ฐฉํ–ฅ์œผ๋กœ_๋“ฑ๋ก์‹œ_๊ธฐ์ค€์—ญ์ด_๊ตฌ๊ฐ„์˜_์‹œ์ž‘์—_์กด์žฌํ• _๊ฒฝ์šฐ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ธฐ์กด_๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_๊ฐ™๊ฑฐ๋‚˜_ํฌ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค(final int value) { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // expect + assertThatThrownBy(() -> line.add(new Station("A"), new Station("D"), new Distance(value), RIGHT)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("๋“ฑ๋กํ•  ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ธฐ์กด ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @ValueSource(ints = {5, 6}) + @ParameterizedTest(name = "{displayName} ์ž…๋ ฅ: {0}") + void ์ƒํ–‰๋ฐฉํ–ฅ์œผ๋กœ_๋“ฑ๋ก์‹œ_๊ธฐ์ค€์—ญ์ด_๊ตฌ๊ฐ„์˜_๋์—_์กด์žฌํ• _๊ฒฝ์šฐ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ธฐ์กด_๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_๊ฐ™๊ฑฐ๋‚˜_ํฌ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค(final int value) { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // expect + assertThatThrownBy(() -> line.add(new Station("C"), new Station("D"), new Distance(value), LEFT)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("๋“ฑ๋กํ•  ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ธฐ์กด ๊ตฌ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ตฌ๊ฐ„_์‚ฌ์ด์—_์˜ค๋ฅธ์ชฝ์œผ๋กœ_์—ญ์„_์ƒˆ๋กœ_๋“ฑ๋กํ•˜๋Š”_๊ฒฝ์šฐ_๊ฑฐ๋ฆฌ๊ฐ€_์žฌ๊ณ„์‚ฐ๋œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.add(new Station("A"), new Station("D"), new Distance(3), RIGHT); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("B", "C", 5), + new Section("A", "D", 3), + new Section("D", "B", 2) + )); + } + + @Test + void ์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ตฌ๊ฐ„_์‚ฌ์ด์—_์™ผ์ชฝ์œผ๋กœ_์—ญ์„_์ƒˆ๋กœ_๋“ฑ๋กํ•˜๋Š”_๊ฒฝ์šฐ_๊ฑฐ๋ฆฌ๊ฐ€_์žฌ๊ณ„์‚ฐ๋œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.add(new Station("C"), new Station("D"), new Distance(3), LEFT); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("A", "B", 5), + new Section("B", "D", 2), + new Section("D", "C", 3) + )); + } + + @Test + void ๋…ธ์„ _์˜ค๋ฅธ์ชฝ_๋์—_๊ตฌ๊ฐ„์„_๋“ฑ๋กํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.add(new Station("C"), new Station("D"), new Distance(3), RIGHT); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5), + new Section("C", "D", 3) + )); + } + + @Test + void ๋…ธ์„ _์™ผ์ชฝ_๋์—_๊ตฌ๊ฐ„์„_๋“ฑ๋กํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.add(new Station("A"), new Station("D"), new Distance(3), LEFT); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("D", "A", 3), + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + } + + @ParameterizedTest(name = "์ž…๋ ฅ๋ฐ›์€ ๋…ธ์„ ๋ช…๊ณผ ๋™์ผํ•œ์ง€ ํ™•์ธํ•œ๋‹ค. ๊ธฐ์กด: 1ํ˜ธ์„ , ์ž…๋ ฅ: {0}, ๊ฒฐ๊ณผ: {1}") + @CsvSource({"1ํ˜ธ์„ , true", "2ํ˜ธ์„ , false"}) + void ์ž…๋ ฅ๋ฐ›์€_๋…ธ์„ ๋ช…๊ณผ_๋™์ผํ•œ์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final boolean result) { + // given + final Line line = new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList()); + + // expect + assertThat(line.isSameName(name)).isEqualTo(result); + } + + @Test + void ์ œ๊ฑฐํ•˜๋ ค๋Š”_์—ญ์ด_์—†๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // expect + assertThatThrownBy(() -> line.remove(new Station("D"))) + .isInstanceOf(StationNotFoundException.class) + .hasMessage("์—ญ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ์ค‘๊ฐ„์—_์žˆ๋Š”_์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.remove(new Station("B")); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("A", "C", 10) + )); + } + + @Test + void ์ƒํ–‰_์ข…์ ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.remove(new Station("A")); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("B", "C", 5) + )); + } + + @Test + void ํ•˜ํ–‰_์ข…์ ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + line.remove(new Station("C")); + + // then + assertThat(line.getSections()).containsAll(List.of( + new Section("A", "B", 5) + )); + } + + @Test + void ๋‚จ์•„์žˆ๋Š”_์—ญ์ด_๋‘๊ฐœ์ธ_๊ฒฝ์šฐ_๋‘_์—ญ_๋ชจ๋‘_์ œ๊ฑฐํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5) + )); + + // when + line.remove(new Station("A")); + + // then + assertThat(line.getSections()).isEmpty(); + } + + @Test + void ๋…ธ์„ ์—_ํฌํ•จ๋œ_์—ญ์„_์ˆœ์„œ๋Œ€๋กœ_๋ณด์—ฌ์ค˜์•ผ_ํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + + // when + List stations = line.findAllStation(); + + // then + assertThat(stations).containsExactly( + new Station("A"), + new Station("B"), + new Station("C"), + new Station("D"), + new Station("E") + ); + } + + @Test + void ๋…ธ์„ ์—_๋น„์–ด์žˆ๋Š”_๊ฒฝ์šฐ_๋นˆ_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + + // when + List stations = line.findAllStation(); + + // then + assertThat(stations).isEmpty(); + } + + @Test + void ๋…ธ์„ ์—_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + + // when + line.initialAdd(new Section("A", "B", 3)); + + // then + assertThat(line.getSections()).contains(new Section("A", "B", 3)); + } + + @Test + void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_๋…ธ์„ ์ด_๋น„์–ด์žˆ์ง€_์•Š์€_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3) + )); + + // expect + assertThatThrownBy(() -> line.initialAdd(new Section("A", "B", 3))) + .isInstanceOf(LineNotEmptyException.class) + .hasMessage("๋…ธ์„ ์ด ๋น„์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ์ด๋ฆ„๊ณผ_์ƒ‰์„_๋ณ€๊ฒฝํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + + // when + line.changeNameAndColor("3ํ˜ธ์„ ", "ORANGE"); + + // then + assertAll( + () -> assertThat(line.getName()).isEqualTo("3ํ˜ธ์„ "), + () -> assertThat(line.getColor()).isEqualTo("ORANGE") + ); + } +} + diff --git a/src/test/java/subway/domain/SectionTest.java b/src/test/java/subway/domain/SectionTest.java new file mode 100644 index 000000000..908eb32f4 --- /dev/null +++ b/src/test/java/subway/domain/SectionTest.java @@ -0,0 +1,114 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class SectionTest { + + @CsvSource({"A, true", "C, false"}) + @ParameterizedTest(name = "Section(A, B)์ผ ๋•Œ {0}์„ ํฌํ•จํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๊ฒฐ๊ณผ: {1}") + void ํ•˜๋‚˜์˜_์—ญ์ด_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final boolean result) { + // given + final Section section = new Section("A", "B", 5); + + // expect + assertThat(section.contains(new Station(name))).isEqualTo(result); + } + + @CsvSource({"A, B, true", "B, C, false", "B, A, true"}) + @ParameterizedTest(name = "Section(A, B)์ผ ๋•Œ {0}๊ณผ {1}์„ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๊ฒฐ๊ณผ: {2}") + void ๋‘๊ฐœ_์—ญ_๋ชจ๋‘_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(final String start, final String end, final boolean result) { + // given + final Section section = new Section("A", "B", 5); + + // expect + assertThat(section.containsAll(new Station(start), new Station(end))).isEqualTo(result); + } + + @ParameterizedTest(name = "Section(A, B)์˜ ๊ฑฐ๋ฆฌ๊ฐ€ 3์ผ ๋•Œ ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์ด ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค. ์ž…๋ ฅ: {0}, ๊ฒฐ๊ณผ: {1}") + @CsvSource({"2, false", "3, true", "4, true"}) + void ์ž์‹ ์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_ํฌ๊ฑฐ๋‚˜_๊ฐ™์€์ง€_ํ™•์ธํ•œ๋‹ค(final int value, final boolean result) { + // given + final Section section = new Section("A", "B", 3); + + // expect + assertThat(section.moreThanOrEqual(new Distance(value))).isEqualTo(result); + } + + @CsvSource({"A, LEFT, true", "B, LEFT, false", "B, RIGHT, true", "B, LEFT, false"}) + @ParameterizedTest(name = "Section(A, B)์ผ ๋•Œ {0}์ด {1} ์œ„์น˜์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๊ฒฐ๊ณผ: {2}") + void ์ž…๋ ฅ๋ฐ›์€_์—ญ์ด_์ž…๋ ฅ๋ฐ›์€_์œ„์น˜์—_์กด์žฌํ•˜๋Š”์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final Direction direction, final boolean result) { + // given + final Section section = new Section("A", "B", 5); + + // expect + assertThat(section.isStationExistsAtDirection(new Station(name), direction)).isEqualTo(result); + } + + @Test + void ํ˜„์žฌ_๊ฑฐ๋ฆฌ์—์„œ_์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๋ฅผ_๋บ€_๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Section section = new Section("A", "B", 5); + + // when + final Distance result = section.subtract(new Distance(2)); + + // then + assertThat(result).isEqualTo(new Distance(3)); + } + + @Test + void ํ˜„์žฌ_๊ฑฐ๋ฆฌ์—์„œ_์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๋ฅผ_๋”ํ•œ_๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Section section = new Section("A", "B", 5); + + // when + final Distance result = section.add(new Distance(2)); + + // then + assertThat(result).isEqualTo(new Distance(7)); + } + + @Test + void ์‹œ์ž‘์—ญ_์ด๋ฆ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Section section = new Section("A", "B", 5); + + // when + final String result = section.getStartName(); + + // then + assertThat(result).isEqualTo("A"); + } + + @Test + void ๋„์ฐฉ์—ญ_์ด๋ฆ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Section section = new Section("A", "B", 5); + + // when + final String result = section.getEndName(); + + // then + assertThat(result).isEqualTo("B"); + } + + @Test + void ๊ฑฐ๋ฆฌ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Section section = new Section("A", "B", 5); + + // when + final Integer result = section.getDistanceValue(); + + // then + assertThat(result).isEqualTo(5); + } +} diff --git a/src/test/java/subway/domain/StationTest.java b/src/test/java/subway/domain/StationTest.java new file mode 100644 index 000000000..6e220a670 --- /dev/null +++ b/src/test/java/subway/domain/StationTest.java @@ -0,0 +1,33 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class StationTest { + + @CsvSource({"A, true", "B, false"}) + @ParameterizedTest(name = "์—ญ A์™€ ์ด๋ฆ„์ด ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค. ์ž…๋ ฅ: {0}, ๊ฒฐ๊ณผ: {1}") + void ์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ˜„์žฌ_์—ญ์ด๋ž‘_์ด๋ฆ„์ด_๊ฐ™์€์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final boolean result) { + // given + final Station station = new Station("A"); + + // expect + assertThat(station.isSameName(name)).isEqualTo(result); + } + + @CsvSource({"A, true", "B, false"}) + @ParameterizedTest(name = "์—ญ A์™€ ์ด๋ฆ„์ด ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค. ์ž…๋ ฅ: {0}, ๊ฒฐ๊ณผ: {1}") + void ๋‹ค๋ฅธ_์—ญ์„_์ž…๋ ฅ๋ฐ›์•„_ํ˜„์žฌ_์—ญ์ด๋ž‘_์ด๋ฆ„์ด_๊ฐ™์€์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final boolean result) { + // given + final Station station = new Station("A"); + + // expect + assertThat(station.isSameName(new Station(name))).isEqualTo(result); + } +} diff --git a/src/test/java/subway/domain/SubwayTest.java b/src/test/java/subway/domain/SubwayTest.java new file mode 100644 index 000000000..e63272ca6 --- /dev/null +++ b/src/test/java/subway/domain/SubwayTest.java @@ -0,0 +1,178 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static subway.domain.Direction.LEFT; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.exception.InvalidSectionException; +import subway.exception.LineNotEmptyException; +import subway.exception.LineNotFoundException; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class SubwayTest { + + @Test + void ์—ญ_์ถ”๊ฐ€์‹œ_์ „์ฒด_๋ผ์ธ์—์„œ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Line line1 = new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + final Line line2 = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("Z", "B", 5), + new Section("B", "Y", 5) + )); + final Subway subway = new Subway(List.of(line1, line2)); + + // expect + assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, LEFT)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("์ง€ํ•˜์ฒ  ์ „์ฒด ๋…ธ์„ ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค."); + } + + @Test + void ์—ญ_์ถ”๊ฐ€์‹œ_์ž…๋ ฅํ•œ_๋…ธ์„ _์ด๋ฆ„์ด_์กด์žฌํ•˜์ง€_์•Š์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(Collections.emptyList()); + + // expect + assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, LEFT)) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์ •์ƒ์ ์œผ๋กœ_๋“ฑ๋ก๋œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )), + new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("Z", "B", 5), + new Section("B", "Y", 5) + )) + )); + + // when + subway.add("1ํ˜ธ์„ ", "B", "D", 3, LEFT); + + // then + assertThat(subway.getLines()).flatExtracting(Line::getSections).containsAll(List.of( + new Section("A", "D", 2), + new Section("D", "B", 3), + new Section("B", "C", 5), + new Section("Z", "B", 5), + new Section("B", "Y", 5) + )); + } + + @Test + void ์—ญ_์ œ๊ฑฐ์‹œ_์ž…๋ ฅํ•œ_๋…ธ์„ _์ด๋ฆ„์ด_์กด์žฌํ•˜์ง€_์•Š์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(Collections.emptyList()); + + // expect + assertThatThrownBy(() -> subway.remove("1ํ˜ธ์„ ", "B")) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์ •์ƒ์ ์œผ๋กœ_์ œ๊ฑฐ๋œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )) + )); + + // when + subway.remove("1ํ˜ธ์„ ", "B"); + + // then + assertThat(subway.getLines()).flatExtracting(Line::getSections).containsAll(List.of( + new Section("A", "C", 10) + )); + } + + @Test + void ๋…ธ์„ ์—_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()) + )); + + // when + subway.initialAdd("2ํ˜ธ์„ ", "A", "B", 4); + + // then + assertThat(subway.getLines()).flatExtracting(Line::getSections).containsAll(List.of( + new Section("A", "B", 4) + )); + } + + @Test + void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_๋…ธ์„ ์ด_๋น„์–ด์žˆ์ง€_์•Š์€_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3) + )) + )); + + // expect + assertThatThrownBy(() -> subway.initialAdd("2ํ˜ธ์„ ", "A", "B", 4)) + .isInstanceOf(LineNotEmptyException.class) + .hasMessage("๋…ธ์„ ์ด ๋น„์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_์ด๋ฆ„์ด_๊ฐ™์€_์—ญ์„_์ถ”๊ฐ€ํ•˜๋ ค๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()) + )); + + // expect + assertThatThrownBy(() -> subway.initialAdd("2ํ˜ธ์„ ", "A", "A", 4)) + .isInstanceOf(InvalidSectionException.class) + .hasMessage("๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์—ญ์„ ๊ตฌ๊ฐ„์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ๋…ธ์„ ์˜_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_๋…ธ์„ ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList()), + new Line("2ํ˜ธ์„ ", "BLUE", Collections.emptyList()) + )); + + // when + final Line line = subway.findLineByName("1ํ˜ธ์„ "); + + // expect + assertThat(line.getName()).isEqualTo("1ํ˜ธ์„ "); + } + + @Test + void ๋…ธ์„ ์˜_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_๋…ธ์„ ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”๋‹ค๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "BLUE", Collections.emptyList()) + )); + + // expect + assertThatThrownBy(() -> subway.findLineByName("1ํ˜ธ์„ ")) + .isInstanceOf(LineNotFoundException.class) + .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } +} diff --git a/src/test/java/subway/domain/strategy/AddStationStrategyTest.java b/src/test/java/subway/domain/strategy/AddStationStrategyTest.java new file mode 100644 index 000000000..72e818324 --- /dev/null +++ b/src/test/java/subway/domain/strategy/AddStationStrategyTest.java @@ -0,0 +1,38 @@ +package subway.domain.strategy; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.Direction; +import subway.domain.Section; +import subway.domain.Station; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AddStationStrategyTest { + + private AddStationStrategy sut = (sections, base, additional, distance) -> { + }; + + @Test + void ์ž…๋ ฅํ•œ_์—ญ์ด_์ž…๋ ฅํ•œ_๋ฐฉํ–ฅ์—_์กด์žฌํ•˜๋Š”_๊ตฌ๊ฐ„์„_๊ฒ€์ƒ‰ํ•˜์—ฌ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + List
sections = List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + ); + + // when + final Section result = sut.findSectionByStationExistsAtDirection( + sections, + new Station("A"), + Direction.LEFT + ).get(); + + // then + assertThat(result).isEqualTo(new Section("A", "B", 5)); + } +} diff --git a/src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java b/src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java new file mode 100644 index 000000000..74710a11b --- /dev/null +++ b/src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java @@ -0,0 +1,57 @@ +package subway.domain.strategy; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.Distance; +import subway.domain.Section; +import subway.domain.Station; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AddStationToLeftStrategyTest { + + final AddStationStrategy addStationToLeftStrategy = new AddStationToLeftStrategy(); + + @Test + void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์™ผ์ชฝ_๋ฐฉํ–ฅ์œผ๋กœ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + List
sections = new ArrayList<>(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + addStationToLeftStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); + + // then + assertThat(sections).contains( + new Section("A", "D", 3), + new Section("D", "B", 2), + new Section("B", "C", 5) + ); + } + + @Test + void ๊ตฌ๊ฐ„_์™ผ์ชฝ_๋์—_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + List
sections = new ArrayList<>(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + addStationToLeftStrategy.add(sections, new Station("A"), new Station("D"), new Distance(2)); + + // then + assertThat(sections).contains( + new Section("D", "A", 2), + new Section("A", "B", 5), + new Section("B", "C", 5) + ); + } +} diff --git a/src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java b/src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java new file mode 100644 index 000000000..67dcb17f8 --- /dev/null +++ b/src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java @@ -0,0 +1,57 @@ +package subway.domain.strategy; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.Distance; +import subway.domain.Section; +import subway.domain.Station; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AddStationToRightStrategyTest { + + final AddStationStrategy addStationToLeftStrategy = new AddStationToRightStrategy(); + + @Test + void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์˜ค๋ฅธ์ชฝ_๋ฐฉํ–ฅ์œผ๋กœ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + List
sections = new ArrayList<>(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + addStationToLeftStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); + + // then + assertThat(sections).contains( + new Section("A", "B", 5), + new Section("B", "D", 2), + new Section("D", "C", 3) + ); + } + + @Test + void ๊ตฌ๊ฐ„_์˜ค๋ฅธ์ชฝ_๋์—_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + List
sections = new ArrayList<>(List.of( + new Section("A", "B", 5), + new Section("B", "C", 5) + )); + + // when + addStationToLeftStrategy.add(sections, new Station("C"), new Station("D"), new Distance(2)); + + // then + assertThat(sections).contains( + new Section("A", "B", 5), + new Section("B", "C", 5), + new Section("C", "D", 2) + ); + } +} diff --git a/src/test/java/subway/dto/LineResponseTest.java b/src/test/java/subway/dto/LineResponseTest.java new file mode 100644 index 000000000..a8c61c1b9 --- /dev/null +++ b/src/test/java/subway/dto/LineResponseTest.java @@ -0,0 +1,37 @@ +package subway.dto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.Line; +import subway.domain.Section; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class LineResponseTest { + + @Test + void ๋ผ์ธ์„_๋ฐ›์•„_์ƒ์„ฑํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + + // when + final LineResponse result = LineResponse.from(line); + + // then + assertAll( + () -> assertThat(result.getName()).isEqualTo("2ํ˜ธ์„ "), + () -> assertThat(result.getColor()).isEqualTo("RED"), + () -> assertThat(result.getStations()).containsExactly("A", "B", "C", "D", "E") + ); + } +} diff --git a/src/test/java/subway/integration/IntegrationTest.java b/src/test/java/subway/integration/IntegrationTest.java deleted file mode 100644 index c30949402..000000000 --- a/src/test/java/subway/integration/IntegrationTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package subway.integration; - -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.annotation.DirtiesContext; - -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class IntegrationTest { - @LocalServerPort - int port; - - @BeforeEach - public void setUp() { - RestAssured.port = port; - } -} diff --git a/src/test/java/subway/integration/LineIntegrationTest.java b/src/test/java/subway/integration/LineIntegrationTest.java deleted file mode 100644 index ad4170205..000000000 --- a/src/test/java/subway/integration/LineIntegrationTest.java +++ /dev/null @@ -1,190 +0,0 @@ -package subway.integration; - -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import subway.dto.LineRequest; -import subway.dto.LineResponse; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -@DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ") -public class LineIntegrationTest extends IntegrationTest { - private LineRequest lineRequest1; - private LineRequest lineRequest2; - - @BeforeEach - public void setUp() { - super.setUp(); - - lineRequest1 = new LineRequest("์‹ ๋ถ„๋‹น์„ ", "bg-red-600"); - lineRequest2 = new LineRequest("๊ตฌ์‹ ๋ถ„๋‹น์„ ", "bg-red-600"); - } - - @DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์ƒ์„ฑํ•œ๋‹ค.") - @Test - void createLine() { - // when - ExtractableResponse response = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); - assertThat(response.header("Location")).isNotBlank(); - } - - @DisplayName("๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ์ง€ํ•˜์ฒ  ๋…ธ์„  ์ด๋ฆ„์œผ๋กœ ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์ƒ์„ฑํ•œ๋‹ค.") - @Test - void createLineWithDuplicateName() { - // given - RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // when - ExtractableResponse response = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); - } - - @DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„  ๋ชฉ๋ก์„ ์กฐํšŒํ•œ๋‹ค.") - @Test - void getLines() { - // given - ExtractableResponse createResponse1 = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - ExtractableResponse createResponse2 = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest2) - .when().post("/lines") - .then().log().all(). - extract(); - - // when - ExtractableResponse response = RestAssured - .given().log().all() - .accept(MediaType.APPLICATION_JSON_VALUE) - .when().get("/lines") - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - List expectedLineIds = Stream.of(createResponse1, createResponse2) - .map(it -> Long.parseLong(it.header("Location").split("/")[2])) - .collect(Collectors.toList()); - List resultLineIds = response.jsonPath().getList(".", LineResponse.class).stream() - .map(LineResponse::getId) - .collect(Collectors.toList()); - assertThat(resultLineIds).containsAll(expectedLineIds); - } - - @DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์กฐํšŒํ•œ๋‹ค.") - @Test - void getLine() { - // given - ExtractableResponse createResponse = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // when - Long lineId = Long.parseLong(createResponse.header("Location").split("/")[2]); - ExtractableResponse response = RestAssured - .given().log().all() - .accept(MediaType.APPLICATION_JSON_VALUE) - .when().get("/lines/{lineId}", lineId) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - LineResponse resultResponse = response.as(LineResponse.class); - assertThat(resultResponse.getId()).isEqualTo(lineId); - } - - @DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์ˆ˜์ •ํ•œ๋‹ค.") - @Test - void updateLine() { - // given - ExtractableResponse createResponse = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // when - Long lineId = Long.parseLong(createResponse.header("Location").split("/")[2]); - ExtractableResponse response = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest2) - .when().put("/lines/{lineId}", lineId) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - @DisplayName("์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์ œ๊ฑฐํ•œ๋‹ค.") - @Test - void deleteLine() { - // given - ExtractableResponse createResponse = RestAssured - .given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(lineRequest1) - .when().post("/lines") - .then().log().all(). - extract(); - - // when - Long lineId = Long.parseLong(createResponse.header("Location").split("/")[2]); - ExtractableResponse response = RestAssured - .given().log().all() - .when().delete("/lines/{lineId}", lineId) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); - } -} diff --git a/src/test/java/subway/integration/StationIntegrationTest.java b/src/test/java/subway/integration/StationIntegrationTest.java deleted file mode 100644 index a97d184a0..000000000 --- a/src/test/java/subway/integration/StationIntegrationTest.java +++ /dev/null @@ -1,197 +0,0 @@ -package subway.integration; - -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import subway.dto.StationResponse; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -@DisplayName("์ง€ํ•˜์ฒ ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ") -public class StationIntegrationTest extends IntegrationTest { - @DisplayName("์ง€ํ•˜์ฒ ์—ญ์„ ์ƒ์„ฑํ•œ๋‹ค.") - @Test - void createStation() { - // given - Map params = new HashMap<>(); - params.put("name", "๊ฐ•๋‚จ์—ญ"); - - // when - ExtractableResponse response = RestAssured.given().log().all() - .body(params) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); - assertThat(response.header("Location")).isNotBlank(); - } - - @DisplayName("๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ์ง€ํ•˜์ฒ ์—ญ ์ด๋ฆ„์œผ๋กœ ์ง€ํ•˜์ฒ ์—ญ์„ ์ƒ์„ฑํ•œ๋‹ค.") - @Test - void createStationWithDuplicateName() { - // given - Map params = new HashMap<>(); - params.put("name", "๊ฐ•๋‚จ์—ญ"); - RestAssured.given().log().all() - .body(params) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // when - ExtractableResponse response = RestAssured.given().log().all() - .body(params) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then() - .log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); - } - - @DisplayName("์ง€ํ•˜์ฒ ์—ญ ๋ชฉ๋ก์„ ์กฐํšŒํ•œ๋‹ค.") - @Test - void getStations() { - /// given - Map params1 = new HashMap<>(); - params1.put("name", "๊ฐ•๋‚จ์—ญ"); - ExtractableResponse createResponse1 = RestAssured.given().log().all() - .body(params1) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - Map params2 = new HashMap<>(); - params2.put("name", "์—ญ์‚ผ์—ญ"); - ExtractableResponse createResponse2 = RestAssured.given().log().all() - .body(params2) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // when - ExtractableResponse response = RestAssured.given().log().all() - .when() - .get("/stations") - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - List expectedStationIds = Stream.of(createResponse1, createResponse2) - .map(it -> Long.parseLong(it.header("Location").split("/")[2])) - .collect(Collectors.toList()); - List resultStationIds = response.jsonPath().getList(".", StationResponse.class).stream() - .map(StationResponse::getId) - .collect(Collectors.toList()); - assertThat(resultStationIds).containsAll(expectedStationIds); - } - - @DisplayName("์ง€ํ•˜์ฒ ์—ญ์„ ์กฐํšŒํ•œ๋‹ค.") - @Test - void getStation() { - /// given - Map params1 = new HashMap<>(); - params1.put("name", "๊ฐ•๋‚จ์—ญ"); - ExtractableResponse createResponse = RestAssured.given().log().all() - .body(params1) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // when - Long stationId = Long.parseLong(createResponse.header("Location").split("/")[2]); - ExtractableResponse response = RestAssured.given().log().all() - .when() - .get("/stations/{stationId}", stationId) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - StationResponse stationResponse = response.as(StationResponse.class); - assertThat(stationResponse.getId()).isEqualTo(stationId); - } - - @DisplayName("์ง€ํ•˜์ฒ ์—ญ์„ ์ˆ˜์ •ํ•œ๋‹ค.") - @Test - void updateStation() { - // given - Map params = new HashMap<>(); - params.put("name", "๊ฐ•๋‚จ์—ญ"); - ExtractableResponse createResponse = RestAssured.given().log().all() - .body(params) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // when - Map otherParams = new HashMap<>(); - otherParams.put("name", "์‚ผ์„ฑ์—ญ"); - String uri = createResponse.header("Location"); - ExtractableResponse response = RestAssured.given().log().all() - .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(otherParams) - .when() - .put(uri) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - @DisplayName("์ง€ํ•˜์ฒ ์—ญ์„ ์ œ๊ฑฐํ•œ๋‹ค.") - @Test - void deleteStation() { - // given - Map params = new HashMap<>(); - params.put("name", "๊ฐ•๋‚จ์—ญ"); - ExtractableResponse createResponse = RestAssured.given().log().all() - .body(params) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .post("/stations") - .then().log().all() - .extract(); - - // when - String uri = createResponse.header("Location"); - ExtractableResponse response = RestAssured.given().log().all() - .when() - .delete(uri) - .then().log().all() - .extract(); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); - } -} diff --git a/src/test/java/subway/repository/LineMapperTest.java b/src/test/java/subway/repository/LineMapperTest.java new file mode 100644 index 000000000..7975bcd74 --- /dev/null +++ b/src/test/java/subway/repository/LineMapperTest.java @@ -0,0 +1,103 @@ +package subway.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.Distance; +import subway.domain.Line; +import subway.domain.Section; +import subway.domain.Station; +import subway.entity.LineEntity; +import subway.entity.SectionEntity; +import subway.entity.StationEntity; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class LineMapperTest { + + private LineMapper lineMapper = new LineMapper(); + + @Test + void Line์„_์ž…๋ ฅ๋ฐ›์•„_SectionEntity_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Long lineId = 1L; + final Line line = new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 2), + new Section("B", "Y", 3) + )); + final List stationEntities = List.of( + new StationEntity(1L, "Z", lineId), + new StationEntity(2L, "B", lineId), + new StationEntity(3L, "Y", lineId) + ); + + // when + final List result = lineMapper.toSectionEntities(line, lineId, stationEntities); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo(List.of( + new SectionEntity(1L, 2L, 2, lineId), + new SectionEntity(2L, 3L, 3, lineId) + )); + } + + @Test + void Line์„_์ž…๋ ฅ๋ฐ›์•„_StationEntity_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Long lineId = 1L; + final Line line = new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 2), + new Section("B", "Y", 3) + )); + + // when + final List result = lineMapper.toStationEntities(line, lineId); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo(List.of( + new StationEntity("Z", lineId), + new StationEntity("B", lineId), + new StationEntity("Y", lineId) + )); + } + + @Test + void ์—”ํ‹ฐํ‹ฐ๋“ค์„_์ž…๋ ฅ๋ฐ›์•„_Line์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final LineEntity lineEntity = new LineEntity(1L, "2ํ˜ธ์„ ", "BLUE"); + final Long lineId = 1L; + final List sectionEntities = List.of( + new SectionEntity(1L, 1L, 2L, 3, lineId), + new SectionEntity(2L, 2L, 3L, 5, lineId) + ); + final List stationEntities = List.of( + new StationEntity(1L, "Z", lineId), + new StationEntity(2L, "B", lineId), + new StationEntity(3L, "Y", lineId) + ); + + // when + final Line result = lineMapper.toLine(lineEntity, sectionEntities, stationEntities); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo( + new Line(1L, "2ํ˜ธ์„ ", "BLUE", List.of( + new Section( + 1L, + new Station(1L, "Z"), + new Station(2L, "B"), + new Distance(3) + ), + new Section( + 2L, + new Station(2L, "B"), + new Station(3L, "Y"), + new Distance(5) + ) + )) + ); + } +} diff --git a/src/test/java/subway/repository/LineRepositoryTest.java b/src/test/java/subway/repository/LineRepositoryTest.java new file mode 100644 index 000000000..2ba9220d4 --- /dev/null +++ b/src/test/java/subway/repository/LineRepositoryTest.java @@ -0,0 +1,114 @@ +package subway.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; +import subway.domain.Line; +import subway.domain.Section; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@Transactional +@SpringBootTest +class LineRepositoryTest { + + @Autowired + private LineRepository lineRepository; + + @Test + void ๋…ธ์„ ์„_์ €์žฅํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + + // when + final Line savedLine = lineRepository.save(line); + + // then + assertThat(savedLine).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(line); + } + + @Test + void ๋…ธ์„ ์„_์กฐํšŒํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + lineRepository.save(line); + + // when + final List result = lineRepository.findAll(); + + // then + assertThat(result.get(0)).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(line); + } + + @Test + void ๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + final Line savedLine = lineRepository.save(line); + final Long id = lineRepository.findIdByName(savedLine.getName()).orElseThrow(); + + // when + lineRepository.deleteById(id); + + // then + assertThat(lineRepository.findAll()).isEmpty(); + } + + @Test + void ์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_๋ผ์ธ์˜_id๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + lineRepository.save(line); + + // when + final Long id = lineRepository.findIdByName("2ํ˜ธ์„ ").orElseThrow(); + + // then + assertThat(id).isPositive(); + } + + @Test + void id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋ผ์ธ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + )); + lineRepository.save(line); + final Long id = lineRepository.findIdByName(line.getName()).orElseThrow(); + + // when + final Line result = lineRepository.findById(id).orElseThrow(); + + // then + assertThat(result).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(line); + } +} diff --git a/src/test/java/subway/ui/LineControllerTest.java b/src/test/java/subway/ui/LineControllerTest.java new file mode 100644 index 000000000..8de1d8962 --- /dev/null +++ b/src/test/java/subway/ui/LineControllerTest.java @@ -0,0 +1,156 @@ +package subway.ui; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import subway.common.IntegrationTest; +import subway.domain.Line; +import subway.domain.Section; +import subway.dto.LineAddRequest; +import subway.dto.LineResponse; +import subway.dto.LineUpdateRequest; +import subway.repository.LineRepository; + +@SuppressWarnings("NonAsciiCharacters") +public class LineControllerTest extends IntegrationTest { + + @Autowired + private LineRepository lineRepository; + + @Test + void ๋…ธ์„ ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/lines") + .then().log().all() + .extract(); + + // then + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()), + () -> assertThat(response.header("Location")).isNotBlank() + ); + } + + @Test + void ๋…ธ์„ id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์กฐํšŒํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/lines/" + id) + .then().log().all() + .extract(); + + // then + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), + () -> assertThat(response.jsonPath().getObject(".", LineResponse.class)).usingRecursiveComparison() + .isEqualTo(new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B"))) + ); + } + + @Test + void ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("B", "C", 3), + new Section("A", "B", 2), + new Section("D", "E", 5), + new Section("C", "D", 4) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("Z", "B", 3), + new Section("B", "Y", 2) + ))); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/lines") + .then().log().all() + .extract(); + + // then + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), + () -> assertThat(response.jsonPath().getList(".", LineResponse.class)).usingRecursiveComparison() + .isEqualTo(List.of( + new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B", "C", "D", "E")), + new LineResponse("2ํ˜ธ์„ ", "BLUE", List.of("Z", "B", "Y")) + )) + ); + } + + @Test + void ๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); + final LineUpdateRequest request = new LineUpdateRequest("2ํ˜ธ์„ ", "BLUE"); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .body(request) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().patch("/lines/" + id) + .then().log().all() + .extract(); + + // then + final Line line = lineRepository.findById(id).orElseThrow(); + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()), + () -> assertThat(line.getName()).isEqualTo("2ํ˜ธ์„ "), + () -> assertThat(line.getColor()).isEqualTo("BLUE") + ); + } + + @Test + void ๋…ธ์„ ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().delete("/lines/" + id) + .then().log().all() + .extract(); + + // then + final List result = lineRepository.findAll(); + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()), + () -> assertThat(result).isEmpty() + ); + } +} diff --git a/src/test/java/subway/ui/StationControllerTest.java b/src/test/java/subway/ui/StationControllerTest.java new file mode 100644 index 000000000..523b006ce --- /dev/null +++ b/src/test/java/subway/ui/StationControllerTest.java @@ -0,0 +1,113 @@ +package subway.ui; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static subway.domain.Direction.RIGHT; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import subway.common.IntegrationTest; +import subway.domain.Line; +import subway.domain.Section; +import subway.dto.StationDeleteRequest; +import subway.dto.StationInitialSaveRequest; +import subway.dto.StationSaveRequest; +import subway.repository.LineRepository; + +@SuppressWarnings("NonAsciiCharacters") +public class StationControllerTest extends IntegrationTest { + + @Autowired + private LineRepository lineRepository; + + @Test + void ์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", RIGHT, 3); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/stations") + .then().log().all() + .extract(); + + // then + final List result = lineRepository.findAll(); + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), + () -> assertThat(result).flatExtracting(Line::getSections) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 2), + new Section("B", "C", 3) + )) + ); + } + + @Test + void ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2) + ))); + final StationDeleteRequest request = new StationDeleteRequest("1ํ˜ธ์„ ", "B"); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().delete("/stations") + .then().log().all() + .extract(); + + // then + final List result = lineRepository.findAll(); + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()), + () -> assertThat(result.get(0).getSections()).isEmpty() + ); + } + + @Test + void ๋…ธ์„ ์˜_์—ญ์ด_์—†์„_๋•Œ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList())); + final StationInitialSaveRequest request = new StationInitialSaveRequest("1ํ˜ธ์„ ", "A", "B", 3); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/stations/init") + .then().log().all() + .extract(); + + // then + final List result = lineRepository.findAll(); + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), + () -> assertThat(result).flatExtracting(Line::getSections) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 3) + )) + ); + } +} diff --git a/src/test/resources/deleteAll.sql b/src/test/resources/deleteAll.sql new file mode 100644 index 000000000..a4edcfeb4 --- /dev/null +++ b/src/test/resources/deleteAll.sql @@ -0,0 +1,6 @@ +DELETE +FROM section; +DELETE +FROM station; +DELETE +FROM line; From ba0e43c3b573db96be043f2416c986bdacf2c37f Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 16 May 2023 22:08:51 +0900 Subject: [PATCH 02/38] =?UTF-8?q?refactor:=20repository=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/subway/repository/LineRepository.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/subway/repository/LineRepository.java b/src/main/java/subway/repository/LineRepository.java index 7f4fd4533..034ba6c33 100644 --- a/src/main/java/subway/repository/LineRepository.java +++ b/src/main/java/subway/repository/LineRepository.java @@ -44,18 +44,14 @@ public LineRepository( public Line save(final Line line) { if (Objects.isNull(line.getId())) { - return saveNewLine(line); + return saveLine(line); } final Line savedLine = findById(line.getId()).orElseThrow(LineNotFoundException::new); - lineDao.update(new LineEntity(line.getId(), line.getName(), line.getColor())); - addNewStation(line); - addNewSection(line); - deleteRemovedSection(line, savedLine); - deleteRemovedStation(line, savedLine); + updateLine(line, savedLine); return findById(line.getId()).orElseThrow(LineNotFoundException::new); } - private Line saveNewLine(final Line line) { + private Line saveLine(final Line line) { final LineEntity lineEntity = lineDao.insert(new LineEntity(line.getName(), line.getColor())); final List stationEntities = lineMapper.toStationEntities(line, lineEntity.getId()); @@ -73,6 +69,14 @@ private Line saveNewLine(final Line line) { .orElseThrow(LineNotFoundException::new); } + private void updateLine(final Line line, final Line savedLine) { + lineDao.update(new LineEntity(line.getId(), line.getName(), line.getColor())); + addNewStation(line); + addNewSection(line); + deleteRemovedSection(line, savedLine); + deleteRemovedStation(line, savedLine); + } + private void addNewStation(final Line line) { line.findAllStation().stream() .filter(station -> Objects.isNull(station.getId())) From c8c9d70e213ff6806bdd4ba3c2500bb56177c4f2 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 16 May 2023 22:11:12 +0900 Subject: [PATCH 03/38] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/application.yml diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 000000000..f414b6fa7 --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,6 @@ +my: + datasource: + url: jdbc:h2:mem:test + username: sa + password: + driver-class-name: org.h2.Driver From f1af934604ad4adf6337bfc3573c2afa61a88fde Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 16 May 2023 22:29:59 +0900 Subject: [PATCH 04/38] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 9b02743a3..c74dc5450 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,13 @@ - [x] ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. - [x] ์ „์ฒด ๋…ธ์„  ์กฐํšŒ - [x] ์ „์ฒด ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. +- [ ] ๊ฒฝ๋กœ ์กฐํšŒ + - [ ] ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. + - [ ] ์š”๊ธˆ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. + - ๊ธฐ๋ณธ์šด์ž„(10ใŽž ์ด๋‚ด): ๊ธฐ๋ณธ์šด์ž„ 1,250์› + - ์ด์šฉ ๊ฑฐ๋ฆฌ ์ดˆ๊ณผ ์‹œ ์ถ”๊ฐ€์šด์ž„ ๋ถ€๊ณผ + - 10km~50km: 5km ๊นŒ์ง€ ๋งˆ๋‹ค 100์› ์ถ”๊ฐ€ + - 50km ์ดˆ๊ณผ: 8km ๊นŒ์ง€ ๋งˆ๋‹ค 100์› ์ถ”๊ฐ€ ### ๐Ÿš‰ ์—ญ API @@ -37,3 +44,10 @@ | ์ˆ˜์ • | PATCH | /lines/{id} | | ์กฐํšŒ | GET | /lines/{id} | | ์ „์ฒด ์กฐํšŒ | GET | /lines | + +### ๊ฒฝ๋กœ ์กฐํšŒ API + +| ๊ธฐ๋Šฅ | Method | URL | +|-------|--------|----------------| +| ๊ฒฝ๋กœ ์กฐํšŒ | POST | /shortest-path | + From ee43e6c7cd2667989c9c38d9ed679c03b0c1897b Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 16 May 2023 22:31:03 +0900 Subject: [PATCH 05/38] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/{ui => controller}/LineController.java | 4 ++-- .../java/subway/{ui => controller}/StationController.java | 4 ++-- .../java/subway/{application => service}/LineService.java | 2 +- .../java/subway/{application => service}/StationService.java | 2 +- .../java/subway/{ui => controller}/LineControllerTest.java | 2 +- .../java/subway/{ui => controller}/StationControllerTest.java | 2 +- .../java/subway/{application => service}/LineServiceTest.java | 2 +- .../subway/{application => service}/StationServiceTest.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) rename src/main/java/subway/{ui => controller}/LineController.java (96%) rename src/main/java/subway/{ui => controller}/StationController.java (95%) rename src/main/java/subway/{application => service}/LineService.java (98%) rename src/main/java/subway/{application => service}/StationService.java (98%) rename src/test/java/subway/{ui => controller}/LineControllerTest.java (99%) rename src/test/java/subway/{ui => controller}/StationControllerTest.java (99%) rename src/test/java/subway/{application => service}/LineServiceTest.java (99%) rename src/test/java/subway/{application => service}/StationServiceTest.java (99%) diff --git a/src/main/java/subway/ui/LineController.java b/src/main/java/subway/controller/LineController.java similarity index 96% rename from src/main/java/subway/ui/LineController.java rename to src/main/java/subway/controller/LineController.java index ea5c67676..24c39b810 100644 --- a/src/main/java/subway/ui/LineController.java +++ b/src/main/java/subway/controller/LineController.java @@ -1,4 +1,4 @@ -package subway.ui; +package subway.controller; import java.net.URI; import java.util.List; @@ -12,10 +12,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import subway.application.LineService; import subway.dto.LineAddRequest; import subway.dto.LineResponse; import subway.dto.LineUpdateRequest; +import subway.service.LineService; @RequestMapping("/lines") @RestController diff --git a/src/main/java/subway/ui/StationController.java b/src/main/java/subway/controller/StationController.java similarity index 95% rename from src/main/java/subway/ui/StationController.java rename to src/main/java/subway/controller/StationController.java index 5d322d54b..bf5d39c71 100644 --- a/src/main/java/subway/ui/StationController.java +++ b/src/main/java/subway/controller/StationController.java @@ -1,4 +1,4 @@ -package subway.ui; +package subway.controller; import javax.validation.Valid; import org.springframework.http.ResponseEntity; @@ -7,10 +7,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import subway.application.StationService; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; import subway.dto.StationSaveRequest; +import subway.service.StationService; @RequestMapping("/stations") @RestController diff --git a/src/main/java/subway/application/LineService.java b/src/main/java/subway/service/LineService.java similarity index 98% rename from src/main/java/subway/application/LineService.java rename to src/main/java/subway/service/LineService.java index 3e167f2c5..f7565e583 100644 --- a/src/main/java/subway/application/LineService.java +++ b/src/main/java/subway/service/LineService.java @@ -1,4 +1,4 @@ -package subway.application; +package subway.service; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/subway/application/StationService.java b/src/main/java/subway/service/StationService.java similarity index 98% rename from src/main/java/subway/application/StationService.java rename to src/main/java/subway/service/StationService.java index c56f52415..6d83ec27b 100644 --- a/src/main/java/subway/application/StationService.java +++ b/src/main/java/subway/service/StationService.java @@ -1,4 +1,4 @@ -package subway.application; +package subway.service; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/test/java/subway/ui/LineControllerTest.java b/src/test/java/subway/controller/LineControllerTest.java similarity index 99% rename from src/test/java/subway/ui/LineControllerTest.java rename to src/test/java/subway/controller/LineControllerTest.java index 8de1d8962..106482cd4 100644 --- a/src/test/java/subway/ui/LineControllerTest.java +++ b/src/test/java/subway/controller/LineControllerTest.java @@ -1,4 +1,4 @@ -package subway.ui; +package subway.controller; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; diff --git a/src/test/java/subway/ui/StationControllerTest.java b/src/test/java/subway/controller/StationControllerTest.java similarity index 99% rename from src/test/java/subway/ui/StationControllerTest.java rename to src/test/java/subway/controller/StationControllerTest.java index 523b006ce..e4f406761 100644 --- a/src/test/java/subway/ui/StationControllerTest.java +++ b/src/test/java/subway/controller/StationControllerTest.java @@ -1,4 +1,4 @@ -package subway.ui; +package subway.controller; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; diff --git a/src/test/java/subway/application/LineServiceTest.java b/src/test/java/subway/service/LineServiceTest.java similarity index 99% rename from src/test/java/subway/application/LineServiceTest.java rename to src/test/java/subway/service/LineServiceTest.java index a0e8e2cfd..627296237 100644 --- a/src/test/java/subway/application/LineServiceTest.java +++ b/src/test/java/subway/service/LineServiceTest.java @@ -1,4 +1,4 @@ -package subway.application; +package subway.service; import static java.lang.Long.MAX_VALUE; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/subway/application/StationServiceTest.java b/src/test/java/subway/service/StationServiceTest.java similarity index 99% rename from src/test/java/subway/application/StationServiceTest.java rename to src/test/java/subway/service/StationServiceTest.java index e66a627d5..86f21f804 100644 --- a/src/test/java/subway/application/StationServiceTest.java +++ b/src/test/java/subway/service/StationServiceTest.java @@ -1,4 +1,4 @@ -package subway.application; +package subway.service; import static org.assertj.core.api.Assertions.assertThat; import static subway.domain.Direction.RIGHT; From deb51c2297b85ed3ac9d18886f8f86cf915baeec Mon Sep 17 00:00:00 2001 From: greeng00se Date: Tue, 16 May 2023 22:32:31 +0900 Subject: [PATCH 06/38] =?UTF-8?q?refactor:=20StationService=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/service/StationService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/subway/service/StationService.java b/src/main/java/subway/service/StationService.java index 6d83ec27b..d702b8838 100644 --- a/src/main/java/subway/service/StationService.java +++ b/src/main/java/subway/service/StationService.java @@ -30,8 +30,8 @@ public void initialSave(final StationInitialSaveRequest request) { saveLine(subway, request.getLineName()); } - private void saveLine(final Subway subway, final String request) { - final Line line = subway.findLineByName(request); + private void saveLine(final Subway subway, final String name) { + final Line line = subway.findLineByName(name); lineRepository.save(line); } From d41ebd484bd7472bb2eea97b3297b9aa6ee77cfb Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 01:31:56 +0900 Subject: [PATCH 07/38] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AddStationStrategy.java | 6 +--- .../AddStationToLeftStrategy.java | 7 ++-- .../AddStationToRightStrategy.java | 7 ++-- .../subway/domain/{ => core}/Direction.java | 5 +-- .../subway/domain/{ => core}/Distance.java | 6 +++- .../java/subway/domain/{ => core}/Line.java | 6 ++-- .../subway/domain/{ => core}/Section.java | 4 +-- .../subway/domain/{ => core}/Station.java | 2 +- .../java/subway/domain/{ => core}/Subway.java | 11 ++++++- src/main/java/subway/dto/LineResponse.java | 4 +-- .../java/subway/dto/StationSaveRequest.java | 2 +- .../java/subway/repository/LineMapper.java | 8 ++--- .../subway/repository/LineRepository.java | 6 ++-- src/main/java/subway/service/LineService.java | 2 +- .../java/subway/service/StationService.java | 4 +-- .../subway/common/steps/SectionSteps.java | 6 ++-- .../subway/controller/LineControllerTest.java | 4 +-- .../controller/StationControllerTest.java | 6 ++-- .../AddStationStrategyTest.java | 5 +-- .../AddStationToLeftStrategyTest.java | 5 +-- .../AddStationToRightStrategyTest.java | 5 +-- .../domain/{ => core}/DirectionTest.java | 2 +- .../domain/{ => core}/DistanceTest.java | 2 +- .../subway/domain/{ => core}/LineTest.java | 6 ++-- .../subway/domain/{ => core}/SectionTest.java | 2 +- .../subway/domain/{ => core}/StationTest.java | 2 +- .../subway/domain/{ => core}/SubwayTest.java | 32 +++++++++++++++++-- .../java/subway/dto/LineResponseTest.java | 4 +-- .../subway/repository/LineMapperTest.java | 8 ++--- .../subway/repository/LineRepositoryTest.java | 4 +-- .../java/subway/service/LineServiceTest.java | 4 +-- .../subway/service/StationServiceTest.java | 6 ++-- 32 files changed, 101 insertions(+), 82 deletions(-) rename src/main/java/subway/domain/{strategy => core}/AddStationStrategy.java (78%) rename src/main/java/subway/domain/{strategy => core}/AddStationToLeftStrategy.java (81%) rename src/main/java/subway/domain/{strategy => core}/AddStationToRightStrategy.java (81%) rename src/main/java/subway/domain/{ => core}/Direction.java (79%) rename src/main/java/subway/domain/{ => core}/Distance.java (92%) rename src/main/java/subway/domain/{ => core}/Line.java (98%) rename src/main/java/subway/domain/{ => core}/Section.java (97%) rename src/main/java/subway/domain/{ => core}/Station.java (97%) rename src/main/java/subway/domain/{ => core}/Subway.java (86%) rename src/test/java/subway/domain/{strategy => core}/AddStationStrategyTest.java (88%) rename src/test/java/subway/domain/{strategy => core}/AddStationToLeftStrategyTest.java (92%) rename src/test/java/subway/domain/{strategy => core}/AddStationToRightStrategyTest.java (92%) rename src/test/java/subway/domain/{ => core}/DirectionTest.java (97%) rename src/test/java/subway/domain/{ => core}/DistanceTest.java (98%) rename src/test/java/subway/domain/{ => core}/LineTest.java (98%) rename src/test/java/subway/domain/{ => core}/SectionTest.java (99%) rename src/test/java/subway/domain/{ => core}/StationTest.java (97%) rename src/test/java/subway/domain/{ => core}/SubwayTest.java (85%) diff --git a/src/main/java/subway/domain/strategy/AddStationStrategy.java b/src/main/java/subway/domain/core/AddStationStrategy.java similarity index 78% rename from src/main/java/subway/domain/strategy/AddStationStrategy.java rename to src/main/java/subway/domain/core/AddStationStrategy.java index 7fee18e20..2c9359814 100644 --- a/src/main/java/subway/domain/strategy/AddStationStrategy.java +++ b/src/main/java/subway/domain/core/AddStationStrategy.java @@ -1,11 +1,7 @@ -package subway.domain.strategy; +package subway.domain.core; import java.util.List; import java.util.Optional; -import subway.domain.Direction; -import subway.domain.Distance; -import subway.domain.Section; -import subway.domain.Station; public interface AddStationStrategy { diff --git a/src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java b/src/main/java/subway/domain/core/AddStationToLeftStrategy.java similarity index 81% rename from src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java rename to src/main/java/subway/domain/core/AddStationToLeftStrategy.java index cc87bbb10..af1c266d6 100644 --- a/src/main/java/subway/domain/strategy/AddStationToLeftStrategy.java +++ b/src/main/java/subway/domain/core/AddStationToLeftStrategy.java @@ -1,12 +1,9 @@ -package subway.domain.strategy; +package subway.domain.core; -import static subway.domain.Direction.RIGHT; +import static subway.domain.core.Direction.RIGHT; import java.util.List; import java.util.Optional; -import subway.domain.Distance; -import subway.domain.Section; -import subway.domain.Station; public class AddStationToLeftStrategy implements AddStationStrategy { @Override diff --git a/src/main/java/subway/domain/strategy/AddStationToRightStrategy.java b/src/main/java/subway/domain/core/AddStationToRightStrategy.java similarity index 81% rename from src/main/java/subway/domain/strategy/AddStationToRightStrategy.java rename to src/main/java/subway/domain/core/AddStationToRightStrategy.java index d5db5e6ff..ee24df0f7 100644 --- a/src/main/java/subway/domain/strategy/AddStationToRightStrategy.java +++ b/src/main/java/subway/domain/core/AddStationToRightStrategy.java @@ -1,12 +1,9 @@ -package subway.domain.strategy; +package subway.domain.core; -import static subway.domain.Direction.LEFT; +import static subway.domain.core.Direction.LEFT; import java.util.List; import java.util.Optional; -import subway.domain.Distance; -import subway.domain.Section; -import subway.domain.Station; public class AddStationToRightStrategy implements AddStationStrategy { @Override diff --git a/src/main/java/subway/domain/Direction.java b/src/main/java/subway/domain/core/Direction.java similarity index 79% rename from src/main/java/subway/domain/Direction.java rename to src/main/java/subway/domain/core/Direction.java index 58e4c9a29..3465ae38f 100644 --- a/src/main/java/subway/domain/Direction.java +++ b/src/main/java/subway/domain/core/Direction.java @@ -1,9 +1,6 @@ -package subway.domain; +package subway.domain.core; import java.util.List; -import subway.domain.strategy.AddStationStrategy; -import subway.domain.strategy.AddStationToLeftStrategy; -import subway.domain.strategy.AddStationToRightStrategy; public enum Direction { LEFT(new AddStationToLeftStrategy()), diff --git a/src/main/java/subway/domain/Distance.java b/src/main/java/subway/domain/core/Distance.java similarity index 92% rename from src/main/java/subway/domain/Distance.java rename to src/main/java/subway/domain/core/Distance.java index c46b591d0..cd1a1852b 100644 --- a/src/main/java/subway/domain/Distance.java +++ b/src/main/java/subway/domain/core/Distance.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import java.util.Objects; import subway.exception.DistanceNotValidException; @@ -9,6 +9,10 @@ public class Distance { private final int value; + public Distance(final Double value) { + this(value.intValue()); + } + public Distance(final int value) { validate(value); this.value = value; diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/core/Line.java similarity index 98% rename from src/main/java/subway/domain/Line.java rename to src/main/java/subway/domain/core/Line.java index 51c54e735..2353b0391 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/core/Line.java @@ -1,9 +1,9 @@ -package subway.domain; +package subway.domain.core; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; -import static subway.domain.Direction.LEFT; -import static subway.domain.Direction.RIGHT; +import static subway.domain.core.Direction.LEFT; +import static subway.domain.core.Direction.RIGHT; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/subway/domain/Section.java b/src/main/java/subway/domain/core/Section.java similarity index 97% rename from src/main/java/subway/domain/Section.java rename to src/main/java/subway/domain/core/Section.java index ee2388a6f..2975eb0ec 100644 --- a/src/main/java/subway/domain/Section.java +++ b/src/main/java/subway/domain/core/Section.java @@ -1,6 +1,6 @@ -package subway.domain; +package subway.domain.core; -import static subway.domain.Direction.LEFT; +import static subway.domain.core.Direction.LEFT; import java.util.Objects; diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/core/Station.java similarity index 97% rename from src/main/java/subway/domain/Station.java rename to src/main/java/subway/domain/core/Station.java index 497f561db..5526d4e47 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/core/Station.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import java.util.Objects; diff --git a/src/main/java/subway/domain/Subway.java b/src/main/java/subway/domain/core/Subway.java similarity index 86% rename from src/main/java/subway/domain/Subway.java rename to src/main/java/subway/domain/core/Subway.java index c21688254..537573083 100644 --- a/src/main/java/subway/domain/Subway.java +++ b/src/main/java/subway/domain/core/Subway.java @@ -1,9 +1,10 @@ -package subway.domain; +package subway.domain.core; import java.util.ArrayList; import java.util.List; import subway.exception.InvalidSectionException; import subway.exception.LineNotFoundException; +import subway.exception.StationNotFoundException; public class Subway { @@ -65,6 +66,14 @@ public void initialAdd( findLine.initialAdd(new Section(left, right, new Distance((distance)))); } + public Station findStationByName(final String name) { + return lines.stream() + .flatMap(line -> line.findAllStation().stream()) + .filter(station -> station.isSameName(name)) + .findAny() + .orElseThrow(StationNotFoundException::new); + } + public List getLines() { return lines; } diff --git a/src/main/java/subway/dto/LineResponse.java b/src/main/java/subway/dto/LineResponse.java index 1fc5c5dce..52834f417 100644 --- a/src/main/java/subway/dto/LineResponse.java +++ b/src/main/java/subway/dto/LineResponse.java @@ -3,8 +3,8 @@ import static java.util.stream.Collectors.toList; import java.util.List; -import subway.domain.Line; -import subway.domain.Station; +import subway.domain.core.Line; +import subway.domain.core.Station; public class LineResponse { diff --git a/src/main/java/subway/dto/StationSaveRequest.java b/src/main/java/subway/dto/StationSaveRequest.java index 1e80b1ab0..1d347d452 100644 --- a/src/main/java/subway/dto/StationSaveRequest.java +++ b/src/main/java/subway/dto/StationSaveRequest.java @@ -3,7 +3,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Positive; -import subway.domain.Direction; +import subway.domain.core.Direction; public class StationSaveRequest { diff --git a/src/main/java/subway/repository/LineMapper.java b/src/main/java/subway/repository/LineMapper.java index 9a94ce1bc..1f6b7519e 100644 --- a/src/main/java/subway/repository/LineMapper.java +++ b/src/main/java/subway/repository/LineMapper.java @@ -7,10 +7,10 @@ import java.util.Map; import java.util.Objects; import org.springframework.stereotype.Component; -import subway.domain.Distance; -import subway.domain.Line; -import subway.domain.Section; -import subway.domain.Station; +import subway.domain.core.Distance; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Station; import subway.entity.LineEntity; import subway.entity.SectionEntity; import subway.entity.StationEntity; diff --git a/src/main/java/subway/repository/LineRepository.java b/src/main/java/subway/repository/LineRepository.java index 034ba6c33..6dfc4c461 100644 --- a/src/main/java/subway/repository/LineRepository.java +++ b/src/main/java/subway/repository/LineRepository.java @@ -14,9 +14,9 @@ import subway.dao.LineDao; import subway.dao.SectionDao; import subway.dao.StationDao; -import subway.domain.Line; -import subway.domain.Section; -import subway.domain.Station; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Station; import subway.entity.LineEntity; import subway.entity.SectionEntity; import subway.entity.StationEntity; diff --git a/src/main/java/subway/service/LineService.java b/src/main/java/subway/service/LineService.java index f7565e583..37f3dc4ba 100644 --- a/src/main/java/subway/service/LineService.java +++ b/src/main/java/subway/service/LineService.java @@ -7,7 +7,7 @@ import java.util.Optional; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import subway.domain.Line; +import subway.domain.core.Line; import subway.dto.LineAddRequest; import subway.dto.LineResponse; import subway.dto.LineUpdateRequest; diff --git a/src/main/java/subway/service/StationService.java b/src/main/java/subway/service/StationService.java index d702b8838..73ac6ed8a 100644 --- a/src/main/java/subway/service/StationService.java +++ b/src/main/java/subway/service/StationService.java @@ -2,8 +2,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import subway.domain.Line; -import subway.domain.Subway; +import subway.domain.core.Line; +import subway.domain.core.Subway; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; import subway.dto.StationSaveRequest; diff --git a/src/test/java/subway/common/steps/SectionSteps.java b/src/test/java/subway/common/steps/SectionSteps.java index 8511f0db9..21232231c 100644 --- a/src/test/java/subway/common/steps/SectionSteps.java +++ b/src/test/java/subway/common/steps/SectionSteps.java @@ -4,8 +4,8 @@ import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.springframework.http.MediaType; -import subway.domain.Direction; -import subway.domain.Section; +import subway.domain.core.Direction; +import subway.domain.core.Section; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; import subway.dto.StationSaveRequest; @@ -53,7 +53,7 @@ public class SectionSteps { public static ExtractableResponse ๊ตฌ๊ฐ„_์‚ญ์ œ_์š”์ฒญ(final String ๋…ธ์„ ๋ช…, final String ์‚ญ์ œ์—ญ) { final StationDeleteRequest request = new StationDeleteRequest(๋…ธ์„ ๋ช…, ์‚ญ์ œ์—ญ); - + return RestAssured .given().log().all() .contentType(MediaType.APPLICATION_JSON_VALUE) diff --git a/src/test/java/subway/controller/LineControllerTest.java b/src/test/java/subway/controller/LineControllerTest.java index 106482cd4..c34b1eae5 100644 --- a/src/test/java/subway/controller/LineControllerTest.java +++ b/src/test/java/subway/controller/LineControllerTest.java @@ -12,8 +12,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import subway.common.IntegrationTest; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; import subway.dto.LineAddRequest; import subway.dto.LineResponse; import subway.dto.LineUpdateRequest; diff --git a/src/test/java/subway/controller/StationControllerTest.java b/src/test/java/subway/controller/StationControllerTest.java index e4f406761..ab1cde5f5 100644 --- a/src/test/java/subway/controller/StationControllerTest.java +++ b/src/test/java/subway/controller/StationControllerTest.java @@ -2,7 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import static subway.domain.Direction.RIGHT; +import static subway.domain.core.Direction.RIGHT; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; @@ -14,8 +14,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import subway.common.IntegrationTest; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; import subway.dto.StationSaveRequest; diff --git a/src/test/java/subway/domain/strategy/AddStationStrategyTest.java b/src/test/java/subway/domain/core/AddStationStrategyTest.java similarity index 88% rename from src/test/java/subway/domain/strategy/AddStationStrategyTest.java rename to src/test/java/subway/domain/core/AddStationStrategyTest.java index 72e818324..296efa018 100644 --- a/src/test/java/subway/domain/strategy/AddStationStrategyTest.java +++ b/src/test/java/subway/domain/core/AddStationStrategyTest.java @@ -1,4 +1,4 @@ -package subway.domain.strategy; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; @@ -6,9 +6,6 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.Direction; -import subway.domain.Section; -import subway.domain.Station; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") diff --git a/src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java b/src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java similarity index 92% rename from src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java rename to src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java index 74710a11b..f53a461f2 100644 --- a/src/test/java/subway/domain/strategy/AddStationToLeftStrategyTest.java +++ b/src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java @@ -1,4 +1,4 @@ -package subway.domain.strategy; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; @@ -7,9 +7,6 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.Distance; -import subway.domain.Section; -import subway.domain.Station; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") diff --git a/src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java b/src/test/java/subway/domain/core/AddStationToRightStrategyTest.java similarity index 92% rename from src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java rename to src/test/java/subway/domain/core/AddStationToRightStrategyTest.java index 67dcb17f8..a8b690039 100644 --- a/src/test/java/subway/domain/strategy/AddStationToRightStrategyTest.java +++ b/src/test/java/subway/domain/core/AddStationToRightStrategyTest.java @@ -1,4 +1,4 @@ -package subway.domain.strategy; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; @@ -7,9 +7,6 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.Distance; -import subway.domain.Section; -import subway.domain.Station; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") diff --git a/src/test/java/subway/domain/DirectionTest.java b/src/test/java/subway/domain/core/DirectionTest.java similarity index 97% rename from src/test/java/subway/domain/DirectionTest.java rename to src/test/java/subway/domain/core/DirectionTest.java index 4e87a0989..fe106dfdd 100644 --- a/src/test/java/subway/domain/DirectionTest.java +++ b/src/test/java/subway/domain/core/DirectionTest.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/subway/domain/DistanceTest.java b/src/test/java/subway/domain/core/DistanceTest.java similarity index 98% rename from src/test/java/subway/domain/DistanceTest.java rename to src/test/java/subway/domain/core/DistanceTest.java index 030be513a..dc33bef83 100644 --- a/src/test/java/subway/domain/DistanceTest.java +++ b/src/test/java/subway/domain/core/DistanceTest.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/src/test/java/subway/domain/LineTest.java b/src/test/java/subway/domain/core/LineTest.java similarity index 98% rename from src/test/java/subway/domain/LineTest.java rename to src/test/java/subway/domain/core/LineTest.java index dce3b1366..e6d162a9f 100644 --- a/src/test/java/subway/domain/LineTest.java +++ b/src/test/java/subway/domain/core/LineTest.java @@ -1,10 +1,10 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import static subway.domain.Direction.LEFT; -import static subway.domain.Direction.RIGHT; +import static subway.domain.core.Direction.LEFT; +import static subway.domain.core.Direction.RIGHT; import java.util.Collections; import java.util.List; diff --git a/src/test/java/subway/domain/SectionTest.java b/src/test/java/subway/domain/core/SectionTest.java similarity index 99% rename from src/test/java/subway/domain/SectionTest.java rename to src/test/java/subway/domain/core/SectionTest.java index 908eb32f4..af134a876 100644 --- a/src/test/java/subway/domain/SectionTest.java +++ b/src/test/java/subway/domain/core/SectionTest.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/subway/domain/StationTest.java b/src/test/java/subway/domain/core/StationTest.java similarity index 97% rename from src/test/java/subway/domain/StationTest.java rename to src/test/java/subway/domain/core/StationTest.java index 6e220a670..77845447a 100644 --- a/src/test/java/subway/domain/StationTest.java +++ b/src/test/java/subway/domain/core/StationTest.java @@ -1,4 +1,4 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/subway/domain/SubwayTest.java b/src/test/java/subway/domain/core/SubwayTest.java similarity index 85% rename from src/test/java/subway/domain/SubwayTest.java rename to src/test/java/subway/domain/core/SubwayTest.java index e63272ca6..d16655df5 100644 --- a/src/test/java/subway/domain/SubwayTest.java +++ b/src/test/java/subway/domain/core/SubwayTest.java @@ -1,8 +1,8 @@ -package subway.domain; +package subway.domain.core; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static subway.domain.Direction.LEFT; +import static subway.domain.core.Direction.LEFT; import java.util.Collections; import java.util.List; @@ -12,6 +12,7 @@ import subway.exception.InvalidSectionException; import subway.exception.LineNotEmptyException; import subway.exception.LineNotFoundException; +import subway.exception.StationNotFoundException; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @@ -175,4 +176,31 @@ class SubwayTest { .isInstanceOf(LineNotFoundException.class) .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); } + + @Test + void ์—ญ_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_์—ญ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”๋‹ค๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + )); + + // expect + assertThatThrownBy(() -> subway.findStationByName("C")) + .isInstanceOf(StationNotFoundException.class) + .hasMessage("์—ญ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + + @Test + void ์—ญ_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_์—ญ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + )); + + // when + final Station result = subway.findStationByName("A"); + + // then + assertThat(result.getName()).isEqualTo("A"); + } } diff --git a/src/test/java/subway/dto/LineResponseTest.java b/src/test/java/subway/dto/LineResponseTest.java index a8c61c1b9..a2f8b0554 100644 --- a/src/test/java/subway/dto/LineResponseTest.java +++ b/src/test/java/subway/dto/LineResponseTest.java @@ -7,8 +7,8 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") diff --git a/src/test/java/subway/repository/LineMapperTest.java b/src/test/java/subway/repository/LineMapperTest.java index 7975bcd74..b8b308080 100644 --- a/src/test/java/subway/repository/LineMapperTest.java +++ b/src/test/java/subway/repository/LineMapperTest.java @@ -6,10 +6,10 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.Distance; -import subway.domain.Line; -import subway.domain.Section; -import subway.domain.Station; +import subway.domain.core.Distance; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Station; import subway.entity.LineEntity; import subway.entity.SectionEntity; import subway.entity.StationEntity; diff --git a/src/test/java/subway/repository/LineRepositoryTest.java b/src/test/java/subway/repository/LineRepositoryTest.java index 2ba9220d4..3820a463b 100644 --- a/src/test/java/subway/repository/LineRepositoryTest.java +++ b/src/test/java/subway/repository/LineRepositoryTest.java @@ -9,8 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") diff --git a/src/test/java/subway/service/LineServiceTest.java b/src/test/java/subway/service/LineServiceTest.java index 627296237..e8190e83a 100644 --- a/src/test/java/subway/service/LineServiceTest.java +++ b/src/test/java/subway/service/LineServiceTest.java @@ -12,8 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; import subway.dto.LineAddRequest; import subway.dto.LineResponse; import subway.dto.LineUpdateRequest; diff --git a/src/test/java/subway/service/StationServiceTest.java b/src/test/java/subway/service/StationServiceTest.java index 86f21f804..5291ea0c3 100644 --- a/src/test/java/subway/service/StationServiceTest.java +++ b/src/test/java/subway/service/StationServiceTest.java @@ -1,7 +1,7 @@ package subway.service; import static org.assertj.core.api.Assertions.assertThat; -import static subway.domain.Direction.RIGHT; +import static subway.domain.core.Direction.RIGHT; import java.util.Collections; import java.util.List; @@ -11,8 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; -import subway.domain.Line; -import subway.domain.Section; +import subway.domain.core.Line; +import subway.domain.core.Section; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; import subway.dto.StationSaveRequest; From 0f8522c620055e36538b00255b7b65d2f41d443f Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 09:36:55 +0900 Subject: [PATCH 08/38] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20=EA=B5=AC?= =?UTF-8?q?=EA=B0=84,=20=EC=97=AD=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/core/Subway.java | 14 +++++++ .../java/subway/domain/core/SubwayTest.java | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/main/java/subway/domain/core/Subway.java b/src/main/java/subway/domain/core/Subway.java index 537573083..3895eb725 100644 --- a/src/main/java/subway/domain/core/Subway.java +++ b/src/main/java/subway/domain/core/Subway.java @@ -1,5 +1,7 @@ package subway.domain.core; +import static java.util.stream.Collectors.toList; + import java.util.ArrayList; import java.util.List; import subway.exception.InvalidSectionException; @@ -74,6 +76,18 @@ public Station findStationByName(final String name) { .orElseThrow(StationNotFoundException::new); } + public List
getSections() { + return lines.stream() + .flatMap(line -> line.getSections().stream()) + .collect(toList()); + } + + public List getStations() { + return lines.stream() + .flatMap(line -> line.findAllStation().stream()) + .collect(toList()); + } + public List getLines() { return lines; } diff --git a/src/test/java/subway/domain/core/SubwayTest.java b/src/test/java/subway/domain/core/SubwayTest.java index d16655df5..b00044f34 100644 --- a/src/test/java/subway/domain/core/SubwayTest.java +++ b/src/test/java/subway/domain/core/SubwayTest.java @@ -203,4 +203,41 @@ class SubwayTest { // then assertThat(result.getName()).isEqualTo("A"); } + + @Test + void ๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Section("A", "B", 3), + new Section("B", "C", 5)) + ) + )); + + // when + final List
result = subway.getSections(); + + // then + assertThat(result) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 3), + new Section("B", "C", 5)) + ); + } + + @Test + void ๋ชจ๋“ _์—ญ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + )); + + // when + final List result = subway.getStations(); + + // then + assertThat(result).extracting(Station::getName).contains("A", "B"); + } } From dea88c1b15c18ee06fe749d5035a5f73def0d505 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 09:37:37 +0900 Subject: [PATCH 09/38] =?UTF-8?q?chore:=20jgrapht=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 51eb23d2a..bd610919b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,28 +1,30 @@ plugins { - id 'java' - id 'org.springframework.boot' version '2.7.9' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'java' + id 'org.springframework.boot' version '2.7.9' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' } sourceCompatibility = '11' repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-jdbc' - implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' + implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' - testImplementation 'io.rest-assured:rest-assured:4.4.0' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'io.rest-assured:rest-assured:4.4.0' + testImplementation 'org.springframework.boot:spring-boot-starter-test' - runtimeOnly 'com.h2database:h2' + runtimeOnly 'com.h2database:h2' + + implementation 'org.jgrapht:jgrapht-core:1.5.2' } test { - useJUnitPlatform() + useJUnitPlatform() } From d7aeff9ce125fbebef24da1274a7fcca57858ab0 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 09:44:05 +0900 Subject: [PATCH 10/38] =?UTF-8?q?feat:=20=EC=B5=9C=EB=8B=A8=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=ED=83=90=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/domain/path/PathFindResult.java | 32 ++++++++++++ .../java/subway/domain/path/PathFinder.java | 52 +++++++++++++++++++ .../java/subway/domain/path/SectionEdge.java | 23 ++++++++ .../domain/path/PathFindResultTest.java | 33 ++++++++++++ .../subway/domain/path/PathFinderTest.java | 48 +++++++++++++++++ .../subway/domain/path/SectionEdgeTest.java | 25 +++++++++ 6 files changed, 213 insertions(+) create mode 100644 src/main/java/subway/domain/path/PathFindResult.java create mode 100644 src/main/java/subway/domain/path/PathFinder.java create mode 100644 src/main/java/subway/domain/path/SectionEdge.java create mode 100644 src/test/java/subway/domain/path/PathFindResultTest.java create mode 100644 src/test/java/subway/domain/path/PathFinderTest.java create mode 100644 src/test/java/subway/domain/path/SectionEdgeTest.java diff --git a/src/main/java/subway/domain/path/PathFindResult.java b/src/main/java/subway/domain/path/PathFindResult.java new file mode 100644 index 000000000..37af69618 --- /dev/null +++ b/src/main/java/subway/domain/path/PathFindResult.java @@ -0,0 +1,32 @@ +package subway.domain.path; + +import static java.util.stream.Collectors.toList; + +import java.util.List; +import subway.domain.core.Distance; +import subway.domain.core.Section; + +public class PathFindResult { + + private final Distance distance; + private final List path; + + public PathFindResult(final Distance distance, final List path) { + this.distance = distance; + this.path = path; + } + + public List
toSections() { + return path.stream() + .map(SectionEdge::toSection) + .collect(toList()); + } + + public Distance getDistance() { + return distance; + } + + public List getPath() { + return path; + } +} diff --git a/src/main/java/subway/domain/path/PathFinder.java b/src/main/java/subway/domain/path/PathFinder.java new file mode 100644 index 000000000..bae89ccc6 --- /dev/null +++ b/src/main/java/subway/domain/path/PathFinder.java @@ -0,0 +1,52 @@ +package subway.domain.path; + +import org.jgrapht.GraphPath; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import org.jgrapht.graph.WeightedMultigraph; +import subway.domain.core.Distance; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Station; +import subway.domain.core.Subway; + +public class PathFinder { + + private final Subway subway; + + public PathFinder(final Subway subway) { + this.subway = subway; + } + + public PathFindResult find(final String start, final String end) { + final DijkstraShortestPath shortestPath = initializeShortestPath(); + final GraphPath path = shortestPath.getPath(start, end); + return new PathFindResult(new Distance(path.getWeight()), path.getEdgeList()); + } + + private DijkstraShortestPath initializeShortestPath() { + final WeightedMultigraph graph = new WeightedMultigraph<>(SectionEdge.class); + addVertex(graph); + addEdge(graph); + return new DijkstraShortestPath<>(graph); + } + + private void addVertex(final WeightedMultigraph graph) { + subway.getStations().stream() + .map(Station::getName) + .forEach(graph::addVertex); + } + + private void addEdge(final WeightedMultigraph graph) { + for (final Line line : subway.getLines()) { + addEdgeByLine(graph, line); + } + } + + private void addEdgeByLine(final WeightedMultigraph graph, final Line line) { + for (final Section section : line.getSections()) { + final SectionEdge sectionEdge = new SectionEdge(section, 0); + graph.addEdge(section.getStartName(), section.getEndName(), sectionEdge); + graph.setEdgeWeight(sectionEdge, section.getDistanceValue()); + } + } +} diff --git a/src/main/java/subway/domain/path/SectionEdge.java b/src/main/java/subway/domain/path/SectionEdge.java new file mode 100644 index 000000000..baf6b8612 --- /dev/null +++ b/src/main/java/subway/domain/path/SectionEdge.java @@ -0,0 +1,23 @@ +package subway.domain.path; + +import org.jgrapht.graph.DefaultWeightedEdge; +import subway.domain.core.Section; + +public class SectionEdge extends DefaultWeightedEdge { + + private final Section section; + private final int amount; + + public SectionEdge(final Section section, int amount) { + this.section = section; + this.amount = amount; + } + + public Section toSection() { + return section; + } + + public int getAmount() { + return amount; + } +} diff --git a/src/test/java/subway/domain/path/PathFindResultTest.java b/src/test/java/subway/domain/path/PathFindResultTest.java new file mode 100644 index 000000000..3c8004328 --- /dev/null +++ b/src/test/java/subway/domain/path/PathFindResultTest.java @@ -0,0 +1,33 @@ +package subway.domain.path; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Distance; +import subway.domain.core.Section; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class PathFindResultTest { + + @Test + void ๊ฒฝ๋กœ_์ƒ์˜_๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(5), List.of( + new SectionEdge(new Section("A", "B", 5), 500), + new SectionEdge(new Section("B", "C", 10), 500) + )); + + // when + final List
sections = pathFindResult.toSections(); + + // then + assertThat(sections).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( + new Section("A", "B", 5), + new Section("B", "C", 10) + )); + } +} diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/domain/path/PathFinderTest.java new file mode 100644 index 000000000..737ae641b --- /dev/null +++ b/src/test/java/subway/domain/path/PathFinderTest.java @@ -0,0 +1,48 @@ +package subway.domain.path; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Subway; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class PathFinderTest { + + @Test + void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_ํƒ์ƒ‰ํ•œ๋‹ค() { + // given + final Subway subway = new Subway(List.of( + new Line("1ํ˜ธ์„ ", "RED", List.of( + new Section("A", "B", 2), + new Section("B", "C", 3) + )), + new Line("2ํ˜ธ์„ ", "RED", List.of( + new Section("Z", "B", 4), + new Section("B", "Y", 5) + )) + )); + final PathFinder pathFinder = new PathFinder(subway); + + // when + final PathFindResult pathFindResult = pathFinder.find("A", "Y"); + + // then + assertAll( + () -> assertThat(pathFindResult.getDistance().getValue()).isEqualTo(7), + () -> assertThat(pathFindResult.getPath()) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo(List.of( + new Section("A", "B", 2), + new Section("B", "Y", 5) + )) + ); + } +} diff --git a/src/test/java/subway/domain/path/SectionEdgeTest.java b/src/test/java/subway/domain/path/SectionEdgeTest.java new file mode 100644 index 000000000..c44cbd1cc --- /dev/null +++ b/src/test/java/subway/domain/path/SectionEdgeTest.java @@ -0,0 +1,25 @@ +package subway.domain.path; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Section; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class SectionEdgeTest { + + @Test + void Section์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final SectionEdge sectionEdge = new SectionEdge(new Section("A", "B", 5), 500); + + // when + final Section result = sectionEdge.toSection(); + + // then + assertThat(result).isEqualTo(new Section("A", "B", 5)); + } +} From d87d0c65d1e3489fcff29ba032582f36b6134daf Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 13:02:51 +0900 Subject: [PATCH 11/38] =?UTF-8?q?feat:=20=EC=9A=94=EA=B8=88=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/dao/LineDao.java | 11 ++--- src/main/java/subway/domain/core/Line.java | 19 +++++++-- .../java/subway/domain/path/PathFinder.java | 2 +- .../java/subway/domain/path/SectionEdge.java | 8 ++-- src/main/java/subway/dto/LineAddRequest.java | 11 ++++- src/main/java/subway/dto/LineResponse.java | 10 ++++- src/main/java/subway/entity/LineEntity.java | 12 ++++-- .../java/subway/repository/LineMapper.java | 8 +++- .../subway/repository/LineRepository.java | 6 ++- src/main/java/subway/service/LineService.java | 6 +-- src/main/resources/schema.sql | 7 ++-- .../subway/acceptance/LineAcceptanceTest.java | 24 +++++------ .../acceptance/StationAcceptanceTest.java | 30 +++++++------- .../java/subway/common/steps/LineSteps.java | 11 ++--- .../subway/controller/LineControllerTest.java | 18 ++++----- .../controller/StationControllerTest.java | 6 +-- src/test/java/subway/dao/LineDaoTest.java | 16 ++++---- src/test/java/subway/dao/SectionDaoTest.java | 10 ++--- src/test/java/subway/dao/StationDaoTest.java | 12 +++--- .../java/subway/domain/core/LineTest.java | 40 +++++++++---------- .../java/subway/domain/core/SubwayTest.java | 30 +++++++------- .../subway/domain/path/PathFinderTest.java | 4 +- .../java/subway/dto/LineResponseTest.java | 3 +- .../subway/repository/LineMapperTest.java | 8 ++-- .../subway/repository/LineRepositoryTest.java | 10 ++--- .../java/subway/service/LineServiceTest.java | 19 ++++----- .../subway/service/StationServiceTest.java | 10 ++--- 27 files changed, 199 insertions(+), 152 deletions(-) diff --git a/src/main/java/subway/dao/LineDao.java b/src/main/java/subway/dao/LineDao.java index 37f77f9e4..b1514cc7e 100644 --- a/src/main/java/subway/dao/LineDao.java +++ b/src/main/java/subway/dao/LineDao.java @@ -19,7 +19,8 @@ public class LineDao { new LineEntity( rs.getLong("id"), rs.getString("name"), - rs.getString("color") + rs.getString("color"), + rs.getInt("surcharge") ); public LineDao(final JdbcTemplate jdbcTemplate) { @@ -32,16 +33,16 @@ public LineDao(final JdbcTemplate jdbcTemplate) { public LineEntity insert(final LineEntity line) { final BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(line); Long lineId = jdbcInsert.executeAndReturnKey(parameterSource).longValue(); - return new LineEntity(lineId, line.getName(), line.getColor()); + return new LineEntity(lineId, line.getName(), line.getColor(), line.getSurcharge()); } public List findAll() { - String sql = "SELECT id, name, color FROM LINE"; + String sql = "SELECT * FROM LINE"; return jdbcTemplate.query(sql, rowMapper); } public Optional findById(final Long id) { - String sql = "SELECT id, name, color FROM LINE WHERE id = ?"; + String sql = "SELECT * FROM LINE WHERE id = ?"; try { return Optional.ofNullable(jdbcTemplate.queryForObject(sql, rowMapper, id)); } catch (final EmptyResultDataAccessException e) { @@ -50,7 +51,7 @@ public Optional findById(final Long id) { } public Optional findByName(final String name) { - String sql = "SELECT id, name, color FROM LINE WHERE name = ?"; + String sql = "SELECT * FROM LINE WHERE name = ?"; try { return Optional.ofNullable(jdbcTemplate.queryForObject(sql, rowMapper, name)); } catch (final EmptyResultDataAccessException e) { diff --git a/src/main/java/subway/domain/core/Line.java b/src/main/java/subway/domain/core/Line.java index 2353b0391..08d3288c9 100644 --- a/src/main/java/subway/domain/core/Line.java +++ b/src/main/java/subway/domain/core/Line.java @@ -23,16 +23,24 @@ public class Line { private final Long id; private String name; private String color; + private final Integer surcharge; private final List
sections; - public Line(final String name, final String color, final List
sections) { - this(null, name, color, sections); + public Line(final String name, final String color, final Integer surcharge, final List
sections) { + this(null, name, color, surcharge, sections); } - public Line(final Long id, final String name, final String color, final List
sections) { + public Line( + final Long id, + final String name, + final String color, + final Integer surcharge, + final List
sections + ) { this.id = id; this.name = name; this.color = color; + this.surcharge = surcharge; this.sections = new ArrayList<>(sections); } @@ -172,6 +180,7 @@ public String toString() { "id=" + id + ", name='" + name + '\'' + ", color='" + color + '\'' + + ", surcharge=" + surcharge + ", sections=" + sections + '}'; } @@ -188,6 +197,10 @@ public String getColor() { return color; } + public Integer getSurcharge() { + return surcharge; + } + public List
getSections() { return sections; } diff --git a/src/main/java/subway/domain/path/PathFinder.java b/src/main/java/subway/domain/path/PathFinder.java index bae89ccc6..fa21b0d08 100644 --- a/src/main/java/subway/domain/path/PathFinder.java +++ b/src/main/java/subway/domain/path/PathFinder.java @@ -44,7 +44,7 @@ private void addEdge(final WeightedMultigraph graph) { private void addEdgeByLine(final WeightedMultigraph graph, final Line line) { for (final Section section : line.getSections()) { - final SectionEdge sectionEdge = new SectionEdge(section, 0); + final SectionEdge sectionEdge = new SectionEdge(section, line.getSurcharge()); graph.addEdge(section.getStartName(), section.getEndName(), sectionEdge); graph.setEdgeWeight(sectionEdge, section.getDistanceValue()); } diff --git a/src/main/java/subway/domain/path/SectionEdge.java b/src/main/java/subway/domain/path/SectionEdge.java index baf6b8612..38aba4edd 100644 --- a/src/main/java/subway/domain/path/SectionEdge.java +++ b/src/main/java/subway/domain/path/SectionEdge.java @@ -6,18 +6,18 @@ public class SectionEdge extends DefaultWeightedEdge { private final Section section; - private final int amount; + private final int surcharge; public SectionEdge(final Section section, int amount) { this.section = section; - this.amount = amount; + this.surcharge = amount; } public Section toSection() { return section; } - public int getAmount() { - return amount; + public int getSurcharge() { + return surcharge; } } diff --git a/src/main/java/subway/dto/LineAddRequest.java b/src/main/java/subway/dto/LineAddRequest.java index a8e919fdf..a6ad6e6a4 100644 --- a/src/main/java/subway/dto/LineAddRequest.java +++ b/src/main/java/subway/dto/LineAddRequest.java @@ -1,6 +1,7 @@ package subway.dto; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.PositiveOrZero; public class LineAddRequest { @@ -10,9 +11,13 @@ public class LineAddRequest { @NotBlank(message = "๋…ธ์„  ์ƒ‰์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") private String color; - public LineAddRequest(String name, String color) { + @PositiveOrZero(message = "์ถ”๊ฐ€ ์šด์ž„์€ 0์› ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private int surcharge; + + public LineAddRequest(final String name, final String color, final int surcharge) { this.name = name; this.color = color; + this.surcharge = surcharge; } public String getName() { @@ -22,4 +27,8 @@ public String getName() { public String getColor() { return color; } + + public Integer getSurcharge() { + return surcharge; + } } diff --git a/src/main/java/subway/dto/LineResponse.java b/src/main/java/subway/dto/LineResponse.java index 52834f417..64a1f2c62 100644 --- a/src/main/java/subway/dto/LineResponse.java +++ b/src/main/java/subway/dto/LineResponse.java @@ -10,11 +10,13 @@ public class LineResponse { private final String name; private final String color; + private final Integer surcharge; private final List stations; - public LineResponse(final String name, final String color, final List stations) { + public LineResponse(final String name, final String color, final Integer surcharge, final List stations) { this.name = name; this.color = color; + this.surcharge = surcharge; this.stations = stations; } @@ -22,7 +24,7 @@ public static LineResponse from(final Line line) { final List names = line.findAllStation().stream() .map(Station::getName) .collect(toList()); - return new LineResponse(line.getName(), line.getColor(), names); + return new LineResponse(line.getName(), line.getColor(), line.getSurcharge(), names); } public String getName() { @@ -33,6 +35,10 @@ public String getColor() { return color; } + public Integer getSurcharge() { + return surcharge; + } + public List getStations() { return stations; } diff --git a/src/main/java/subway/entity/LineEntity.java b/src/main/java/subway/entity/LineEntity.java index 7326f9969..fb1efa798 100644 --- a/src/main/java/subway/entity/LineEntity.java +++ b/src/main/java/subway/entity/LineEntity.java @@ -4,15 +4,17 @@ public class LineEntity { private Long id; private String name; private String color; + private Integer surcharge; - public LineEntity(String name, String color) { - this(null, name, color); + public LineEntity(final String name, final String color, final Integer surcharge) { + this(null, name, color, surcharge); } - public LineEntity(Long id, String name, String color) { + public LineEntity(final Long id, final String name, final String color, final Integer surcharge) { this.id = id; this.name = name; this.color = color; + this.surcharge = surcharge; } public Long getId() { @@ -26,4 +28,8 @@ public String getName() { public String getColor() { return color; } + + public Integer getSurcharge() { + return surcharge; + } } diff --git a/src/main/java/subway/repository/LineMapper.java b/src/main/java/subway/repository/LineMapper.java index 1f6b7519e..d89c7cd77 100644 --- a/src/main/java/subway/repository/LineMapper.java +++ b/src/main/java/subway/repository/LineMapper.java @@ -57,7 +57,13 @@ public Line toLine( .map(sectionEntity -> toSection(stationIdByStationName, sectionEntity)) .collect(toList()); - return new Line(lineEntity.getId(), lineEntity.getName(), lineEntity.getColor(), sections); + return new Line( + lineEntity.getId(), + lineEntity.getName(), + lineEntity.getColor(), + lineEntity.getSurcharge(), + sections + ); } private static Section toSection( diff --git a/src/main/java/subway/repository/LineRepository.java b/src/main/java/subway/repository/LineRepository.java index 6dfc4c461..c8fd46146 100644 --- a/src/main/java/subway/repository/LineRepository.java +++ b/src/main/java/subway/repository/LineRepository.java @@ -52,7 +52,9 @@ public Line save(final Line line) { } private Line saveLine(final Line line) { - final LineEntity lineEntity = lineDao.insert(new LineEntity(line.getName(), line.getColor())); + final LineEntity lineEntity = lineDao.insert( + new LineEntity(line.getName(), line.getColor(), line.getSurcharge()) + ); final List stationEntities = lineMapper.toStationEntities(line, lineEntity.getId()); stationDao.insertAll(stationEntities); @@ -70,7 +72,7 @@ private Line saveLine(final Line line) { } private void updateLine(final Line line, final Line savedLine) { - lineDao.update(new LineEntity(line.getId(), line.getName(), line.getColor())); + lineDao.update(new LineEntity(line.getId(), line.getName(), line.getColor(), line.getSurcharge())); addNewStation(line); addNewSection(line); deleteRemovedSection(line, savedLine); diff --git a/src/main/java/subway/service/LineService.java b/src/main/java/subway/service/LineService.java index 37f3dc4ba..c625018ca 100644 --- a/src/main/java/subway/service/LineService.java +++ b/src/main/java/subway/service/LineService.java @@ -1,8 +1,8 @@ package subway.service; +import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; -import java.util.Collections; import java.util.List; import java.util.Optional; import org.springframework.stereotype.Service; @@ -30,8 +30,8 @@ public Long add(final LineAddRequest request) { if (lineId.isPresent()) { throw new LineAlreadyExistsException(); } - return lineRepository.save(new Line(request.getName(), request.getColor(), Collections.emptyList())) - .getId(); + final Line line = new Line(request.getName(), request.getColor(), request.getSurcharge(), emptyList()); + return lineRepository.save(line).getId(); } public void delete(final Long id) { diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 16c5da3ed..c1722432d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,8 +1,9 @@ CREATE TABLE IF NOT EXISTS LINE ( - id BIGINT AUTO_INCREMENT NOT NULL, - name VARCHAR(255) UNIQUE NOT NULL, - color VARCHAR(20) NOT NULL, + id BIGINT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) UNIQUE NOT NULL, + color VARCHAR(20) NOT NULL, + surcharge INT NOT NULL, PRIMARY KEY (id) ); diff --git a/src/test/java/subway/acceptance/LineAcceptanceTest.java b/src/test/java/subway/acceptance/LineAcceptanceTest.java index fd0820e30..b834841de 100644 --- a/src/test/java/subway/acceptance/LineAcceptanceTest.java +++ b/src/test/java/subway/acceptance/LineAcceptanceTest.java @@ -33,7 +33,7 @@ public class ๋…ธ์„ ์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ์ •์ƒ_์š”์ฒญ์˜_๊ฒฝ์šฐ_๋…ธ์„ ์ด_์ •์ƒ์ ์œผ๋กœ_์ถ”๊ฐ€๋œ๋‹ค() { // given - final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘", 0); // expect ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์ƒ์„ฑ); @@ -43,10 +43,10 @@ public class ๋…ธ์„ ์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ์ด๋ฏธ_๊ฐ™์€_์ด๋ฆ„์œผ๋กœ_์ƒ์„ฑ๋œ_๋…ธ์„ ์ด_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘", 0); // when - final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘", 0); // then ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์š”์ฒญ_๊ฒฐ๊ณผ, ๋น„์ •์ƒ_์š”์ฒญ); @@ -59,7 +59,7 @@ public class ๋…ธ์„ ์„_์กฐํšŒํ• _๋•Œ { @Test void ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_์ƒํ–‰์ข…์ ์—ญ_๋ถ€ํ„ฐ_ํ•˜ํ–‰์ข…์ ์—ญ์œผ๋กœ_์ •๋ ฌ๋œ_๊ฒฐ๊ณผ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); final var ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); @@ -68,7 +68,7 @@ public class ๋…ธ์„ ์„_์กฐํšŒํ• _๋•Œ { // then ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); - ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด"); + ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "2ํ˜ธ์„ ", "์ดˆ๋ก", 0, "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด"); } @Test @@ -90,11 +90,11 @@ public class ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ• _๋•Œ { @Test void ์ƒํ–‰์ข…์ ์—ญ_๋ถ€ํ„ฐ_ํ•˜ํ–‰์ข…์ ์—ญ์œผ๋กœ_์ •๋ ฌ๋œ_๊ฒฐ๊ณผ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ", ์˜ค๋ฅธ์ชฝ, 5); - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๊ณ ๋™"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๊ณ ๋™", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", 3); ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „", ์˜ค๋ฅธ์ชฝ, 7); @@ -105,8 +105,8 @@ public class ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ• _๋•Œ { ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( ์กฐํšŒ_๊ฒฐ๊ณผ, - ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ"), - ๋…ธ์„ _์ •๋ณด("9ํ˜ธ์„ ", "๊ณ ๋™", "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „") + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", 0, "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ"), + ๋…ธ์„ _์ •๋ณด("9ํ˜ธ์„ ", "๊ณ ๋™", 0, "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „") ); } } @@ -117,7 +117,7 @@ public class ๋…ธ์„ ์„_์ˆ˜์ •ํ• _๋•Œ { @Test void ๋…ธ์„ _๋ฒˆํ˜ธ์™€_์ˆ˜์ •ํ• _๋‚ด์šฉ์„_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { // given - final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final String ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); // when @@ -126,7 +126,7 @@ public class ๋…ธ์„ ์„_์ˆ˜์ •ํ• _๋•Œ { // then ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์ˆ˜์ •_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ์ด์ง€๋งŒ_๋ฐ˜ํ™˜๊ฐ’_์—†์Œ); final var ์กฐํšŒ_๊ฒฐ๊ณผ = ๋…ธ์„ _์กฐํšŒ_์š”์ฒญ(๋…ธ์„ _๋ฒˆํ˜ธ); - ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + ๋…ธ์„ _์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค(์กฐํšŒ_๊ฒฐ๊ณผ, "1ํ˜ธ์„ ", "ํŒŒ๋ž‘", 0); } @Test @@ -148,7 +148,7 @@ public class ๋…ธ์„ ์„_์‚ญ์ œํ• _๋•Œ { @Test void ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { // given - final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final var ๋…ธ์„ _๋ฒˆํ˜ธ = ๋…ธ์„ _๋ฒˆํ˜ธ๋ฅผ_๊ตฌํ•œ๋‹ค(์ดˆ๋ก์ƒ‰_2ํ˜ธ์„ ); // when diff --git a/src/test/java/subway/acceptance/StationAcceptanceTest.java b/src/test/java/subway/acceptance/StationAcceptanceTest.java index 6c9f7fd8b..c51008491 100644 --- a/src/test/java/subway/acceptance/StationAcceptanceTest.java +++ b/src/test/java/subway/acceptance/StationAcceptanceTest.java @@ -26,7 +26,7 @@ public class ๋นˆ_๋…ธ์„ ์ธ_๊ฒฝ์šฐ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ์„_ํ†ตํ•ด_์—ญ์„_์ถ”๊ฐ€ @Test void ์ด_๋•Œ_์ •์ƒ_์š”์ฒญ์˜_๊ฒฝ์šฐ_์—ญ_๋‘๊ฐœ๊ฐ€_์ •์ƒ์ ์œผ๋กœ_์ถ”๊ฐ€๋œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); // expect @@ -34,14 +34,14 @@ public class ๋นˆ_๋…ธ์„ ์ธ_๊ฒฝ์šฐ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ์„_ํ†ตํ•ด_์—ญ์„_์ถ”๊ฐ€ final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( ์ „์ฒด_๋…ธ์„ _์ •๋ณด, - ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", 0, "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") ); } @Test void ์ด_๋•Œ_๋…ธ์„ ์—_์—ญ์ด_์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); // when @@ -58,7 +58,7 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ๊ธฐ์ค€์—ญ์ด_์กด์žฌํ•œ๋‹ค๋ฉด_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ์„_ํ†ตํ•ด_์—ญ์„_์ถ”๊ฐ€ํ• _์ˆ˜_์žˆ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); // when @@ -69,16 +69,16 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( ์ „์ฒด_๋…ธ์„ _์ •๋ณด, - ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ") + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", 0, "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ") ); } @Test void ์ „์ฒด_๋…ธ์„ ์—_์ƒ์„ฑํ• _๊ตฌ๊ฐ„์ด_์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("1ํ˜ธ์„ ", "ํŒŒ๋ž‘", 0); // when final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); @@ -90,7 +90,7 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ๋“ฑ๋กํ• _์—ญ์ด_๊ฐ™์€_๋…ธ์„ ์—๋Š”_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ", ์˜ค๋ฅธ์ชฝ, 2); @@ -104,7 +104,7 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ๊ธฐ์ค€์—ญ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 5); // when @@ -117,7 +117,7 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ { @Test void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์ถ”๊ฐ€ํ•˜๋Š”_๊ฒฝ์šฐ_๊ตฌ๊ฐ„_์‚ฌ์ด์˜_๊ธธ์ด๋ณด๋‹ค_์ถ”๊ฐ€ํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ฐ™๊ฑฐ๋‚˜_๊ธด๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); // when @@ -134,7 +134,7 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์‚ญ์ œํ• _๋•Œ { @Test void ํ•ด๋‹น_๋…ธ์„ ์—_์—ญ์ด_๋‘๊ฐœ_๋ฐ–์—_์กด์žฌํ•˜์ง€_์•Š๋Š”_๊ฒฝ์šฐ_๋ชจ๋“ _์—ญ์ด_์‚ญ์ œ๋œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); // when @@ -145,14 +145,14 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์‚ญ์ œํ• _๋•Œ { final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( ์ „์ฒด_๋…ธ์„ _์ •๋ณด, - ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก") + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", 0) ); } @Test void ์ •์ƒ_์š”์ฒญ์ธ_๊ฒฝ์šฐ_์—ญ์ด_์‚ญ์ œ๋œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); final var ์š”์ฒญ_๊ฒฐ๊ณผ = ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์ž ์‹ค์ƒˆ๋‚ด", ์™ผ์ชฝ, 2); @@ -164,14 +164,14 @@ public class ๋…ธ์„ ์—_๊ตฌ๊ฐ„์„_์‚ญ์ œํ• _๋•Œ { final var ์ „์ฒด_๋…ธ์„ _์ •๋ณด = ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_์š”์ฒญ(); ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( ์ „์ฒด_๋…ธ์„ _์ •๋ณด, - ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") + ๋…ธ์„ _์ •๋ณด("2ํ˜ธ์„ ", "์ดˆ๋ก", 0, "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด") ); } @Test void ์กด์žฌํ•˜์ง€_์•Š๋Š”_์—ญ์€_์‚ญ์ œ_์š”์ฒญํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() { // given - ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก"); + ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 5); // when diff --git a/src/test/java/subway/common/steps/LineSteps.java b/src/test/java/subway/common/steps/LineSteps.java index ad1b63738..ba9eb0cd0 100644 --- a/src/test/java/subway/common/steps/LineSteps.java +++ b/src/test/java/subway/common/steps/LineSteps.java @@ -16,8 +16,8 @@ @SuppressWarnings("NonAsciiCharacters") public class LineSteps { - public static ExtractableResponse ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ) { - final LineAddRequest request = new LineAddRequest(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ); + public static ExtractableResponse ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ, final Integer ์ถ”๊ฐ€์šด์ž„) { + final LineAddRequest request = new LineAddRequest(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์ถ”๊ฐ€์šด์ž„); return RestAssured .given().log().all() @@ -76,17 +76,18 @@ public class LineSteps { final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ, final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ, + final Integer ์ถ”๊ฐ€์šด์ž„, final String... ์—ญ ) { final List ์—ญ_๋ชจ์Œ = Arrays.stream(์—ญ).collect(Collectors.toList()); assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.jsonPath().getObject(".", LineResponse.class)) .usingRecursiveComparison() - .isEqualTo(new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์—ญ_๋ชจ์Œ)); + .isEqualTo(new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์ถ”๊ฐ€์šด์ž„, ์—ญ_๋ชจ์Œ)); } - public static LineResponse ๋…ธ์„ _์ •๋ณด(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ, final String... ์—ญ) { + public static LineResponse ๋…ธ์„ _์ •๋ณด(final String ๋…ธ์„ ๋ช…, final String ์ƒ‰์ƒ, final Integer ์ถ”๊ฐ€์šด์ž„, final String... ์—ญ) { final List ์—ญ_๋ชจ์Œ = Arrays.stream(์—ญ).collect(Collectors.toList()); - return new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์—ญ_๋ชจ์Œ); + return new LineResponse(๋…ธ์„ ๋ช…, ์ƒ‰์ƒ, ์ถ”๊ฐ€์šด์ž„, ์—ญ_๋ชจ์Œ); } public static void ๋…ธ์„ _์ „์ฒด_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( diff --git a/src/test/java/subway/controller/LineControllerTest.java b/src/test/java/subway/controller/LineControllerTest.java index c34b1eae5..f561003f2 100644 --- a/src/test/java/subway/controller/LineControllerTest.java +++ b/src/test/java/subway/controller/LineControllerTest.java @@ -28,7 +28,7 @@ public class LineControllerTest extends IntegrationTest { @Test void ๋…ธ์„ ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED", 0); // when ExtractableResponse response = RestAssured @@ -49,7 +49,7 @@ public class LineControllerTest extends IntegrationTest { @Test void ๋…ธ์„ id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋…ธ์„ ์„_์กฐํšŒํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); @@ -66,20 +66,20 @@ public class LineControllerTest extends IntegrationTest { assertAll( () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), () -> assertThat(response.jsonPath().getObject(".", LineResponse.class)).usingRecursiveComparison() - .isEqualTo(new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B"))) + .isEqualTo(new LineResponse("1ํ˜ธ์„ ", "RED", 0, List.of("A", "B"))) ); } @Test void ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), new Section("C", "D", 4) ))); - lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 3), new Section("B", "Y", 2) ))); @@ -97,8 +97,8 @@ public class LineControllerTest extends IntegrationTest { () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), () -> assertThat(response.jsonPath().getList(".", LineResponse.class)).usingRecursiveComparison() .isEqualTo(List.of( - new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B", "C", "D", "E")), - new LineResponse("2ํ˜ธ์„ ", "BLUE", List.of("Z", "B", "Y")) + new LineResponse("1ํ˜ธ์„ ", "RED", 0, List.of("A", "B", "C", "D", "E")), + new LineResponse("2ํ˜ธ์„ ", "BLUE", 0, List.of("Z", "B", "Y")) )) ); } @@ -106,7 +106,7 @@ public class LineControllerTest extends IntegrationTest { @Test void ๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); @@ -133,7 +133,7 @@ public class LineControllerTest extends IntegrationTest { @Test void ๋…ธ์„ ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); final Long id = lineRepository.findIdByName("1ํ˜ธ์„ ").orElseThrow(); diff --git a/src/test/java/subway/controller/StationControllerTest.java b/src/test/java/subway/controller/StationControllerTest.java index ab1cde5f5..01b73bc6d 100644 --- a/src/test/java/subway/controller/StationControllerTest.java +++ b/src/test/java/subway/controller/StationControllerTest.java @@ -30,7 +30,7 @@ public class StationControllerTest extends IntegrationTest { @Test void ์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", RIGHT, 3); @@ -61,7 +61,7 @@ public class StationControllerTest extends IntegrationTest { @Test void ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); final StationDeleteRequest request = new StationDeleteRequest("1ํ˜ธ์„ ", "B"); @@ -86,7 +86,7 @@ public class StationControllerTest extends IntegrationTest { @Test void ๋…ธ์„ ์˜_์—ญ์ด_์—†์„_๋•Œ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList())); + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, Collections.emptyList())); final StationInitialSaveRequest request = new StationInitialSaveRequest("1ํ˜ธ์„ ", "A", "B", 3); // when diff --git a/src/test/java/subway/dao/LineDaoTest.java b/src/test/java/subway/dao/LineDaoTest.java index 8be9b7eb6..58e653c6d 100644 --- a/src/test/java/subway/dao/LineDaoTest.java +++ b/src/test/java/subway/dao/LineDaoTest.java @@ -32,7 +32,7 @@ void setUp() { @Test void ๋…ธ์„ ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED", 0); // when final LineEntity result = lineDao.insert(line); @@ -48,9 +48,9 @@ void setUp() { @Test void ๋…ธ์„ ์„_์ˆ˜์ •ํ•œ๋‹ค() { // given - final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED", 0); final LineEntity insertLine = lineDao.insert(line); - final LineEntity newLine = new LineEntity(insertLine.getId(), "2ํ˜ธ์„ ", "BLUE"); + final LineEntity newLine = new LineEntity(insertLine.getId(), "2ํ˜ธ์„ ", "BLUE", 0); // when lineDao.update(newLine); @@ -66,7 +66,7 @@ void setUp() { @Test void ๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { // given - final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED", 0); final LineEntity insertLine = lineDao.insert(line); // when @@ -79,8 +79,8 @@ void setUp() { @Test void ๋…ธ์„ ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line1 = new LineEntity("1ํ˜ธ์„ ", "RED"); - final LineEntity line2 = new LineEntity("2ํ˜ธ์„ ", "BLUE"); + final LineEntity line1 = new LineEntity("1ํ˜ธ์„ ", "RED", 0); + final LineEntity line2 = new LineEntity("2ํ˜ธ์„ ", "BLUE", 0); final LineEntity insertLine1 = lineDao.insert(line1); final LineEntity insertLine2 = lineDao.insert(line2); @@ -94,7 +94,7 @@ void setUp() { @Test void ๋…ธ์„ ์„_id๋กœ_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED", 0); final LineEntity insertLine = lineDao.insert(line); // when @@ -107,7 +107,7 @@ void setUp() { @Test void ๋…ธ์„ ์„_์ด๋ฆ„์œผ๋กœ_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED"); + final LineEntity line = new LineEntity("1ํ˜ธ์„ ", "RED", 0); lineDao.insert(line); // when diff --git a/src/test/java/subway/dao/SectionDaoTest.java b/src/test/java/subway/dao/SectionDaoTest.java index 11558233a..fafa17939 100644 --- a/src/test/java/subway/dao/SectionDaoTest.java +++ b/src/test/java/subway/dao/SectionDaoTest.java @@ -36,7 +36,7 @@ void setUp() { @Test void ๊ตฌ๊ฐ„์„_์ „์ฒด_์ €์žฅํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); @@ -57,7 +57,7 @@ void setUp() { @Test void ๊ตฌ๊ฐ„์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); @@ -78,7 +78,7 @@ void setUp() { @Test void ์ž…๋ ฅ๋ฐ›์€_๋…ธ์„ _id์—_ํ•ด๋‹นํ•˜๋Š”_๊ตฌ๊ฐ„์„_์ „์ฒด_์‚ญ์ œํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); @@ -99,7 +99,7 @@ void setUp() { @Test void ๋ผ์ธ_id๋ฅผ_๋ฐ›์•„_๊ตฌ๊ฐ„์„_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); final StationEntity station3 = stationDao.insert(new StationEntity("C", line.getId())); @@ -120,7 +120,7 @@ void setUp() { @Test void ๊ตฌ๊ฐ„_id๋ฅผ_๋ฐ›์•„_์ œ๊ฑฐํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station1 = stationDao.insert(new StationEntity("A", line.getId())); final StationEntity station2 = stationDao.insert(new StationEntity("B", line.getId())); diff --git a/src/test/java/subway/dao/StationDaoTest.java b/src/test/java/subway/dao/StationDaoTest.java index 9177687cc..e81a27d7c 100644 --- a/src/test/java/subway/dao/StationDaoTest.java +++ b/src/test/java/subway/dao/StationDaoTest.java @@ -34,7 +34,7 @@ void setUp() { @Test void ์—ญ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); stationDao.insertAll(List.of( new StationEntity("A", line.getId()), new StationEntity("B", line.getId()) @@ -53,7 +53,7 @@ void setUp() { @Test void ๋…ธ์„ id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_์—ญ์„_์ „์ฒด_์‚ญ์ œํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); stationDao.insertAll(List.of( new StationEntity("A", line.getId()), new StationEntity("B", line.getId()) @@ -69,7 +69,7 @@ void setUp() { @Test void ์—ญ์„_๋ชจ๋‘_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final List stations = List.of( new StationEntity("A", line.getId()), new StationEntity("B", line.getId()) @@ -85,7 +85,7 @@ void setUp() { @Test void ์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity station = new StationEntity("B", line.getId()); // when @@ -101,7 +101,7 @@ void setUp() { @Test void ๋…ธ์„ _id๋ฅผ_๋ฐ›์•„_์—ญ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); stationDao.insertAll(List.of( new StationEntity("A", line.getId()), new StationEntity("B", line.getId()) @@ -120,7 +120,7 @@ void setUp() { @Test void id๋ฅผ_๋ฐ›์•„_์—ญ์„_์‚ญ์ œํ•œ๋‹ค() { // given - final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED")); + final LineEntity line = lineDao.insert(new LineEntity("1ํ˜ธ์„ ", "RED", 0)); final StationEntity stationEntity = stationDao.insert(new StationEntity("A", line.getId())); // when diff --git a/src/test/java/subway/domain/core/LineTest.java b/src/test/java/subway/domain/core/LineTest.java index e6d162a9f..43c882c03 100644 --- a/src/test/java/subway/domain/core/LineTest.java +++ b/src/test/java/subway/domain/core/LineTest.java @@ -30,7 +30,7 @@ class LineTest { new Section("A", "B", 5), new Section("B", "C", 5) ); - final Line line = new Line("2ํ˜ธ์„ ", "RED", sections); + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, sections); // expect assertThat(line.containsAll(new Station(start), new Station(end))).isEqualTo(result); @@ -39,7 +39,7 @@ class LineTest { @Test void ๋…ธ์„ ์—_๊ธฐ์ค€_์—ญ์ด_์—†์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -53,7 +53,7 @@ class LineTest { @Test void ๋…ธ์„ ์—_๋“ฑ๋กํ• _์—ญ์ด_์žˆ์œผ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -68,7 +68,7 @@ class LineTest { @ParameterizedTest(name = "{displayName} ์ž…๋ ฅ: {0}") void ํ•˜ํ–‰๋ฐฉํ–ฅ์œผ๋กœ_๋“ฑ๋ก์‹œ_๊ธฐ์ค€์—ญ์ด_๊ตฌ๊ฐ„์˜_์‹œ์ž‘์—_์กด์žฌํ• _๊ฒฝ์šฐ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ธฐ์กด_๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_๊ฐ™๊ฑฐ๋‚˜_ํฌ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค(final int value) { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -83,7 +83,7 @@ class LineTest { @ParameterizedTest(name = "{displayName} ์ž…๋ ฅ: {0}") void ์ƒํ–‰๋ฐฉํ–ฅ์œผ๋กœ_๋“ฑ๋ก์‹œ_๊ธฐ์ค€์—ญ์ด_๊ตฌ๊ฐ„์˜_๋์—_์กด์žฌํ• _๊ฒฝ์šฐ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๊ฐ€_๊ธฐ์กด_๊ตฌ๊ฐ„์˜_๊ฑฐ๋ฆฌ๋ณด๋‹ค_๊ฐ™๊ฑฐ๋‚˜_ํฌ๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค(final int value) { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -97,7 +97,7 @@ class LineTest { @Test void ์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ตฌ๊ฐ„_์‚ฌ์ด์—_์˜ค๋ฅธ์ชฝ์œผ๋กœ_์—ญ์„_์ƒˆ๋กœ_๋“ฑ๋กํ•˜๋Š”_๊ฒฝ์šฐ_๊ฑฐ๋ฆฌ๊ฐ€_์žฌ๊ณ„์‚ฐ๋œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -116,7 +116,7 @@ class LineTest { @Test void ์ด๋ฏธ_์กด์žฌํ•˜๋Š”_๊ตฌ๊ฐ„_์‚ฌ์ด์—_์™ผ์ชฝ์œผ๋กœ_์—ญ์„_์ƒˆ๋กœ_๋“ฑ๋กํ•˜๋Š”_๊ฒฝ์šฐ_๊ฑฐ๋ฆฌ๊ฐ€_์žฌ๊ณ„์‚ฐ๋œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -135,7 +135,7 @@ class LineTest { @Test void ๋…ธ์„ _์˜ค๋ฅธ์ชฝ_๋์—_๊ตฌ๊ฐ„์„_๋“ฑ๋กํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -154,7 +154,7 @@ class LineTest { @Test void ๋…ธ์„ _์™ผ์ชฝ_๋์—_๊ตฌ๊ฐ„์„_๋“ฑ๋กํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -174,7 +174,7 @@ class LineTest { @CsvSource({"1ํ˜ธ์„ , true", "2ํ˜ธ์„ , false"}) void ์ž…๋ ฅ๋ฐ›์€_๋…ธ์„ ๋ช…๊ณผ_๋™์ผํ•œ์ง€_ํ™•์ธํ•œ๋‹ค(final String name, final boolean result) { // given - final Line line = new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList()); + final Line line = new Line("1ํ˜ธ์„ ", "RED", 0, Collections.emptyList()); // expect assertThat(line.isSameName(name)).isEqualTo(result); @@ -183,7 +183,7 @@ class LineTest { @Test void ์ œ๊ฑฐํ•˜๋ ค๋Š”_์—ญ์ด_์—†๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -197,7 +197,7 @@ class LineTest { @Test void ์ค‘๊ฐ„์—_์žˆ๋Š”_์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -214,7 +214,7 @@ class LineTest { @Test void ์ƒํ–‰_์ข…์ ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -231,7 +231,7 @@ class LineTest { @Test void ํ•˜ํ–‰_์ข…์ ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); @@ -248,7 +248,7 @@ class LineTest { @Test void ๋‚จ์•„์žˆ๋Š”_์—ญ์ด_๋‘๊ฐœ์ธ_๊ฒฝ์šฐ_๋‘_์—ญ_๋ชจ๋‘_์ œ๊ฑฐํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5) )); @@ -262,7 +262,7 @@ class LineTest { @Test void ๋…ธ์„ ์—_ํฌํ•จ๋œ_์—ญ์„_์ˆœ์„œ๋Œ€๋กœ_๋ณด์—ฌ์ค˜์•ผ_ํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -285,7 +285,7 @@ class LineTest { @Test void ๋…ธ์„ ์—_๋น„์–ด์žˆ๋Š”_๊ฒฝ์šฐ_๋นˆ_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, Collections.emptyList()); // when List stations = line.findAllStation(); @@ -297,7 +297,7 @@ class LineTest { @Test void ๋…ธ์„ ์—_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, Collections.emptyList()); // when line.initialAdd(new Section("A", "B", 3)); @@ -309,7 +309,7 @@ class LineTest { @Test void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_๋…ธ์„ ์ด_๋น„์–ด์žˆ์ง€_์•Š์€_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3) )); @@ -322,7 +322,7 @@ class LineTest { @Test void ์ด๋ฆ„๊ณผ_์ƒ‰์„_๋ณ€๊ฒฝํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()); + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, Collections.emptyList()); // when line.changeNameAndColor("3ํ˜ธ์„ ", "ORANGE"); diff --git a/src/test/java/subway/domain/core/SubwayTest.java b/src/test/java/subway/domain/core/SubwayTest.java index b00044f34..9349e8bf2 100644 --- a/src/test/java/subway/domain/core/SubwayTest.java +++ b/src/test/java/subway/domain/core/SubwayTest.java @@ -21,11 +21,11 @@ class SubwayTest { @Test void ์—ญ_์ถ”๊ฐ€์‹œ_์ „์ฒด_๋ผ์ธ์—์„œ_๋“ฑ๋กํ• _๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final Line line1 = new Line("1ํ˜ธ์„ ", "RED", List.of( + final Line line1 = new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )); - final Line line2 = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line2 = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("Z", "B", 5), new Section("B", "Y", 5) )); @@ -52,11 +52,11 @@ class SubwayTest { void ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์ •์ƒ์ ์œผ๋กœ_๋“ฑ๋ก๋œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("1ํ˜ธ์„ ", "RED", List.of( + new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )), - new Line("2ํ˜ธ์„ ", "RED", List.of( + new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("Z", "B", 5), new Section("B", "Y", 5) )) @@ -90,7 +90,7 @@ class SubwayTest { void ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์ •์ƒ์ ์œผ๋กœ_์ œ๊ฑฐ๋œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("1ํ˜ธ์„ ", "RED", List.of( + new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 5), new Section("B", "C", 5) )) @@ -109,7 +109,7 @@ class SubwayTest { void ๋…ธ์„ ์—_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()) + new Line("2ํ˜ธ์„ ", "RED", 0, Collections.emptyList()) )); // when @@ -125,7 +125,7 @@ class SubwayTest { void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_๋…ธ์„ ์ด_๋น„์–ด์žˆ์ง€_์•Š์€_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "RED", List.of( + new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3) )) )); @@ -140,7 +140,7 @@ class SubwayTest { void ์ดˆ๊ธฐ_๊ตฌ๊ฐ„์„_์ถ”๊ฐ€ํ• _๋•Œ_์ด๋ฆ„์ด_๊ฐ™์€_์—ญ์„_์ถ”๊ฐ€ํ•˜๋ ค๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "RED", Collections.emptyList()) + new Line("2ํ˜ธ์„ ", "RED", 0, Collections.emptyList()) )); // expect @@ -153,8 +153,8 @@ class SubwayTest { void ๋…ธ์„ ์˜_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_๋…ธ์„ ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList()), - new Line("2ํ˜ธ์„ ", "BLUE", Collections.emptyList()) + new Line("1ํ˜ธ์„ ", "RED", 0, Collections.emptyList()), + new Line("2ํ˜ธ์„ ", "BLUE", 0, Collections.emptyList()) )); // when @@ -168,7 +168,7 @@ class SubwayTest { void ๋…ธ์„ ์˜_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_๋…ธ์„ ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”๋‹ค๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", Collections.emptyList()) + new Line("2ํ˜ธ์„ ", "BLUE", 0, Collections.emptyList()) )); // expect @@ -181,7 +181,7 @@ class SubwayTest { void ์—ญ_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_์—ญ์ด_์กด์žฌํ•˜์ง€_์•Š๋Š”๋‹ค๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of(new Section("A", "B", 3))) )); // expect @@ -194,7 +194,7 @@ class SubwayTest { void ์—ญ_์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_ํ•ด๋‹น_์ด๋ฆ„์—_ํ•ด๋‹น๋˜๋Š”_์—ญ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of(new Section("A", "B", 3))) )); // when @@ -208,7 +208,7 @@ class SubwayTest { void ๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", List.of( + new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("A", "B", 3), new Section("B", "C", 5)) ) @@ -231,7 +231,7 @@ class SubwayTest { void ๋ชจ๋“ _์—ญ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", List.of(new Section("A", "B", 3))) + new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of(new Section("A", "B", 3))) )); // when diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/domain/path/PathFinderTest.java index 737ae641b..c55f3c56e 100644 --- a/src/test/java/subway/domain/path/PathFinderTest.java +++ b/src/test/java/subway/domain/path/PathFinderTest.java @@ -19,11 +19,11 @@ class PathFinderTest { void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_ํƒ์ƒ‰ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("1ํ˜ธ์„ ", "RED", List.of( + new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2), new Section("B", "C", 3) )), - new Line("2ํ˜ธ์„ ", "RED", List.of( + new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("Z", "B", 4), new Section("B", "Y", 5) )) diff --git a/src/test/java/subway/dto/LineResponseTest.java b/src/test/java/subway/dto/LineResponseTest.java index a2f8b0554..e89ae048a 100644 --- a/src/test/java/subway/dto/LineResponseTest.java +++ b/src/test/java/subway/dto/LineResponseTest.java @@ -17,7 +17,7 @@ class LineResponseTest { @Test void ๋ผ์ธ์„_๋ฐ›์•„_์ƒ์„ฑํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -31,6 +31,7 @@ class LineResponseTest { assertAll( () -> assertThat(result.getName()).isEqualTo("2ํ˜ธ์„ "), () -> assertThat(result.getColor()).isEqualTo("RED"), + () -> assertThat(result.getSurcharge()).isEqualTo(0), () -> assertThat(result.getStations()).containsExactly("A", "B", "C", "D", "E") ); } diff --git a/src/test/java/subway/repository/LineMapperTest.java b/src/test/java/subway/repository/LineMapperTest.java index b8b308080..e26f218da 100644 --- a/src/test/java/subway/repository/LineMapperTest.java +++ b/src/test/java/subway/repository/LineMapperTest.java @@ -24,7 +24,7 @@ class LineMapperTest { void Line์„_์ž…๋ ฅ๋ฐ›์•„_SectionEntity_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Long lineId = 1L; - final Line line = new Line("2ํ˜ธ์„ ", "BLUE", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 2), new Section("B", "Y", 3) )); @@ -48,7 +48,7 @@ class LineMapperTest { void Line์„_์ž…๋ ฅ๋ฐ›์•„_StationEntity_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Long lineId = 1L; - final Line line = new Line("2ํ˜ธ์„ ", "BLUE", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 2), new Section("B", "Y", 3) )); @@ -67,7 +67,7 @@ class LineMapperTest { @Test void ์—”ํ‹ฐํ‹ฐ๋“ค์„_์ž…๋ ฅ๋ฐ›์•„_Line์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final LineEntity lineEntity = new LineEntity(1L, "2ํ˜ธ์„ ", "BLUE"); + final LineEntity lineEntity = new LineEntity(1L, "2ํ˜ธ์„ ", "BLUE", 0); final Long lineId = 1L; final List sectionEntities = List.of( new SectionEntity(1L, 1L, 2L, 3, lineId), @@ -84,7 +84,7 @@ class LineMapperTest { // then assertThat(result).usingRecursiveComparison().isEqualTo( - new Line(1L, "2ํ˜ธ์„ ", "BLUE", List.of( + new Line(1L, "2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section( 1L, new Station(1L, "Z"), diff --git a/src/test/java/subway/repository/LineRepositoryTest.java b/src/test/java/subway/repository/LineRepositoryTest.java index 3820a463b..17859a57f 100644 --- a/src/test/java/subway/repository/LineRepositoryTest.java +++ b/src/test/java/subway/repository/LineRepositoryTest.java @@ -24,7 +24,7 @@ class LineRepositoryTest { @Test void ๋…ธ์„ ์„_์ €์žฅํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -41,7 +41,7 @@ class LineRepositoryTest { @Test void ๋…ธ์„ ์„_์กฐํšŒํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -59,7 +59,7 @@ class LineRepositoryTest { @Test void ๋…ธ์„ ์„_์‚ญ์ œํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -78,7 +78,7 @@ class LineRepositoryTest { @Test void ์ด๋ฆ„์„_์ž…๋ ฅ๋ฐ›์•„_๋ผ์ธ์˜_id๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), @@ -96,7 +96,7 @@ class LineRepositoryTest { @Test void id๋ฅผ_์ž…๋ ฅ๋ฐ›์•„_๋ผ์ธ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Line line = new Line("2ํ˜ธ์„ ", "RED", List.of( + final Line line = new Line("2ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), diff --git a/src/test/java/subway/service/LineServiceTest.java b/src/test/java/subway/service/LineServiceTest.java index e8190e83a..9c656c71e 100644 --- a/src/test/java/subway/service/LineServiceTest.java +++ b/src/test/java/subway/service/LineServiceTest.java @@ -36,7 +36,7 @@ class LineServiceTest { @Test void ๋ผ์ธ์„_์ €์žฅํ•œ๋‹ค() { // given - final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED", 0); // when final Long id = lineService.add(request); @@ -51,7 +51,7 @@ class LineServiceTest { @Test void ๋ผ์ธ์„_์ €์žฅํ• _๋•Œ_์ด๋ฏธ_๋ผ์ธ์ด_์กด์žฌํ•˜๋Š”_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { // given - final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED", 0); lineService.add(request); // expect @@ -63,7 +63,7 @@ class LineServiceTest { @Test void ๋ผ์ธid๋ฅผ_๋ฐ›์•„์„œ_๋ผ์ธ์„_์‚ญ์ œํ•œ๋‹ค() { // given - final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED"); + final LineAddRequest request = new LineAddRequest("1ํ˜ธ์„ ", "RED", 0); final Long id = lineService.add(request); // when @@ -84,7 +84,7 @@ class LineServiceTest { @Test void ๋ผ์ธ์„_์ˆ˜์ •ํ•œ๋‹ค() { // given - final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED")); + final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED", 0)); final LineUpdateRequest request = new LineUpdateRequest("2ํ˜ธ์„ ", "BLACK"); // when @@ -112,7 +112,7 @@ class LineServiceTest { @Test void ๋ผ์ธid๋กœ_๋ผ์ธ์„_์กฐํšŒํ•œ๋‹ค() { // given - final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED")); + final Long id = lineService.add(new LineAddRequest("1ํ˜ธ์„ ", "RED", 0)); // when final LineResponse result = lineService.findById(id); @@ -121,6 +121,7 @@ class LineServiceTest { assertAll( () -> assertThat(result.getName()).isEqualTo("1ํ˜ธ์„ "), () -> assertThat(result.getColor()).isEqualTo("RED"), + () -> assertThat(result.getSurcharge()).isEqualTo(0), () -> assertThat(result.getStations()).isEmpty() ); } @@ -136,13 +137,13 @@ class LineServiceTest { @Test void ๋ผ์ธ์„_์ „์ฒด_์กฐํšŒํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("B", "C", 3), new Section("A", "B", 2), new Section("D", "E", 5), new Section("C", "D", 4) ))); - lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 3), new Section("B", "Y", 2) ))); @@ -152,8 +153,8 @@ class LineServiceTest { // then assertThat(result).usingRecursiveComparison().isEqualTo(List.of( - new LineResponse("1ํ˜ธ์„ ", "RED", List.of("A", "B", "C", "D", "E")), - new LineResponse("2ํ˜ธ์„ ", "BLUE", List.of("Z", "B", "Y")) + new LineResponse("1ํ˜ธ์„ ", "RED", 0, List.of("A", "B", "C", "D", "E")), + new LineResponse("2ํ˜ธ์„ ", "BLUE", 0, List.of("Z", "B", "Y")) )); } } diff --git a/src/test/java/subway/service/StationServiceTest.java b/src/test/java/subway/service/StationServiceTest.java index 5291ea0c3..67bf44336 100644 --- a/src/test/java/subway/service/StationServiceTest.java +++ b/src/test/java/subway/service/StationServiceTest.java @@ -33,10 +33,10 @@ public class StationServiceTest { @Test void ์—ญ์„_๋“ฑ๋กํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); - lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 2), new Section("B", "Y", 3) ))); @@ -60,11 +60,11 @@ public class StationServiceTest { @Test void ์—ญ์„_์ œ๊ฑฐํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", List.of( + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2), new Section("B", "C", 3) ))); - lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", List.of( + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( new Section("Z", "B", 2), new Section("B", "Y", 3) ))); @@ -87,7 +87,7 @@ public class StationServiceTest { @Test void ๋ผ์ธ์ด_๋น„์–ด์žˆ์„_๋•Œ_์ดˆ๊ธฐ_์—ญ์„_๋“ฑ๋กํ•œ๋‹ค() { // given - lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", Collections.emptyList())); + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, Collections.emptyList())); final StationInitialSaveRequest request = new StationInitialSaveRequest("1ํ˜ธ์„ ", "A", "B", 3); // when From 0faa68c99e6cc53168f219c18747b7e2fe13edd4 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 15:20:57 +0900 Subject: [PATCH 12/38] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=20=ED=83=90?= =?UTF-8?q?=EC=83=89=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=AC=B6=EC=96=B4=EC=84=9C=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/domain/path/PathFindResult.java | 25 +++++++++++++------ .../java/subway/domain/path/PathFinder.java | 2 +- .../java/subway/domain/path/SectionEdge.java | 19 ++++++++++++-- .../domain/path/PathFindResultTest.java | 24 ++++++++++++------ .../subway/domain/path/PathFinderTest.java | 2 +- .../subway/domain/path/SectionEdgeTest.java | 2 +- 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/main/java/subway/domain/path/PathFindResult.java b/src/main/java/subway/domain/path/PathFindResult.java index 37af69618..9a7eb6219 100644 --- a/src/main/java/subway/domain/path/PathFindResult.java +++ b/src/main/java/subway/domain/path/PathFindResult.java @@ -1,7 +1,6 @@ package subway.domain.path; -import static java.util.stream.Collectors.toList; - +import java.util.ArrayList; import java.util.List; import subway.domain.core.Distance; import subway.domain.core.Section; @@ -16,14 +15,24 @@ public PathFindResult(final Distance distance, final List path) { this.path = path; } - public List
toSections() { - return path.stream() - .map(SectionEdge::toSection) - .collect(toList()); + public List> toSections() { + final List> result = new ArrayList<>(); + + List
currentLine = new ArrayList<>(); + long currentLineId = 0; + for (SectionEdge sectionEdge : path) { + if (currentLine.isEmpty() || currentLineId != sectionEdge.getLineId()) { + currentLine = new ArrayList<>(); + currentLineId = sectionEdge.getLineId(); + result.add(currentLine); + } + currentLine.add(sectionEdge.toSection()); + } + return result; } - public Distance getDistance() { - return distance; + public int getDistanceValue() { + return distance.getValue(); } public List getPath() { diff --git a/src/main/java/subway/domain/path/PathFinder.java b/src/main/java/subway/domain/path/PathFinder.java index fa21b0d08..23af833a8 100644 --- a/src/main/java/subway/domain/path/PathFinder.java +++ b/src/main/java/subway/domain/path/PathFinder.java @@ -44,7 +44,7 @@ private void addEdge(final WeightedMultigraph graph) { private void addEdgeByLine(final WeightedMultigraph graph, final Line line) { for (final Section section : line.getSections()) { - final SectionEdge sectionEdge = new SectionEdge(section, line.getSurcharge()); + final SectionEdge sectionEdge = new SectionEdge(section, line.getSurcharge(), line.getId()); graph.addEdge(section.getStartName(), section.getEndName(), sectionEdge); graph.setEdgeWeight(sectionEdge, section.getDistanceValue()); } diff --git a/src/main/java/subway/domain/path/SectionEdge.java b/src/main/java/subway/domain/path/SectionEdge.java index 38aba4edd..5d00cc7d4 100644 --- a/src/main/java/subway/domain/path/SectionEdge.java +++ b/src/main/java/subway/domain/path/SectionEdge.java @@ -7,10 +7,12 @@ public class SectionEdge extends DefaultWeightedEdge { private final Section section; private final int surcharge; + private final long lineId; - public SectionEdge(final Section section, int amount) { + public SectionEdge(final Section section, final int surcharge, final long lineId) { this.section = section; - this.surcharge = amount; + this.surcharge = surcharge; + this.lineId = lineId; } public Section toSection() { @@ -20,4 +22,17 @@ public Section toSection() { public int getSurcharge() { return surcharge; } + + public long getLineId() { + return lineId; + } + + @Override + public String toString() { + return "SectionEdge{" + + "section=" + section + + ", surcharge=" + surcharge + + ", lineId=" + lineId + + '}'; + } } diff --git a/src/test/java/subway/domain/path/PathFindResultTest.java b/src/test/java/subway/domain/path/PathFindResultTest.java index 3c8004328..b174e199b 100644 --- a/src/test/java/subway/domain/path/PathFindResultTest.java +++ b/src/test/java/subway/domain/path/PathFindResultTest.java @@ -14,20 +14,30 @@ class PathFindResultTest { @Test - void ๊ฒฝ๋กœ_์ƒ์˜_๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + void ๊ฒฝ๋กœ_์ƒ์˜_๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ผ์ธ_๊ธฐ์ค€์œผ๋กœ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final PathFindResult pathFindResult = new PathFindResult(new Distance(5), List.of( - new SectionEdge(new Section("A", "B", 5), 500), - new SectionEdge(new Section("B", "C", 10), 500) + new SectionEdge(new Section("A", "B", 5), 500, 1), + new SectionEdge(new Section("B", "C", 10), 500, 1), + new SectionEdge(new Section("C", "T", 10), 500, 2), + new SectionEdge(new Section("T", "D", 10), 500, 1) )); // when - final List
sections = pathFindResult.toSections(); + final List> result = pathFindResult.toSections(); // then - assertThat(sections).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( - new Section("A", "B", 5), - new Section("B", "C", 10) + assertThat(result).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( + List.of( + new Section("A", "B", 5), + new Section("B", "C", 10) + ), + List.of( + new Section("C", "T", 10) + ), + List.of( + new Section("T", "D", 10) + ) )); } } diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/domain/path/PathFinderTest.java index c55f3c56e..b98474d97 100644 --- a/src/test/java/subway/domain/path/PathFinderTest.java +++ b/src/test/java/subway/domain/path/PathFinderTest.java @@ -35,7 +35,7 @@ class PathFinderTest { // then assertAll( - () -> assertThat(pathFindResult.getDistance().getValue()).isEqualTo(7), + () -> assertThat(pathFindResult.getDistanceValue()).isEqualTo(7), () -> assertThat(pathFindResult.getPath()) .usingRecursiveComparison() .ignoringExpectedNullFields() diff --git a/src/test/java/subway/domain/path/SectionEdgeTest.java b/src/test/java/subway/domain/path/SectionEdgeTest.java index c44cbd1cc..a91bffbfc 100644 --- a/src/test/java/subway/domain/path/SectionEdgeTest.java +++ b/src/test/java/subway/domain/path/SectionEdgeTest.java @@ -14,7 +14,7 @@ class SectionEdgeTest { @Test void Section์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final SectionEdge sectionEdge = new SectionEdge(new Section("A", "B", 5), 500); + final SectionEdge sectionEdge = new SectionEdge(new Section("A", "B", 5), 500, 1); // when final Section result = sectionEdge.toSection(); From 2946f62ae2e6c92f017c09ed50536a0bd4bf1a58 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 15:21:19 +0900 Subject: [PATCH 13/38] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=20=EC=9A=B4?= =?UTF-8?q?=EC=9E=84=20=EC=A0=95=EC=B1=85,=20=EA=B1=B0=EB=A6=AC=20?= =?UTF-8?q?=EB=B3=84=20=EC=9A=B4=EC=9E=84=20=EC=A0=95=EC=B1=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/domain/fare/BaseFarePolicy.java | 13 +++++ .../domain/fare/DistanceFarePolicy.java | 34 +++++++++++ .../java/subway/domain/fare/FarePolicy.java | 8 +++ .../domain/fare/BaseFarePolicyTest.java | 29 ++++++++++ .../domain/fare/DistanceFarePolicyTest.java | 56 +++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 src/main/java/subway/domain/fare/BaseFarePolicy.java create mode 100644 src/main/java/subway/domain/fare/DistanceFarePolicy.java create mode 100644 src/main/java/subway/domain/fare/FarePolicy.java create mode 100644 src/test/java/subway/domain/fare/BaseFarePolicyTest.java create mode 100644 src/test/java/subway/domain/fare/DistanceFarePolicyTest.java diff --git a/src/main/java/subway/domain/fare/BaseFarePolicy.java b/src/main/java/subway/domain/fare/BaseFarePolicy.java new file mode 100644 index 000000000..c3d867286 --- /dev/null +++ b/src/main/java/subway/domain/fare/BaseFarePolicy.java @@ -0,0 +1,13 @@ +package subway.domain.fare; + +import subway.domain.path.PathFindResult; + +public class BaseFarePolicy implements FarePolicy { + + private static final int BASE_AMOUNT = 1250; + + @Override + public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + return fare + BASE_AMOUNT; + } +} diff --git a/src/main/java/subway/domain/fare/DistanceFarePolicy.java b/src/main/java/subway/domain/fare/DistanceFarePolicy.java new file mode 100644 index 000000000..fdf5ee8bc --- /dev/null +++ b/src/main/java/subway/domain/fare/DistanceFarePolicy.java @@ -0,0 +1,34 @@ +package subway.domain.fare; + +import static java.lang.Math.max; +import static java.lang.Math.min; + +import subway.domain.path.PathFindResult; + +public class DistanceFarePolicy implements FarePolicy { + + private static final int NO_EXTRA_FARE_DISTANCE = 10; + private static final int EXTRA_FARE_SEGMENT = 50; + private static final int EXTRA_FARE_BY_UNIT = 100; + private static final int LESS_THAN_OR_EQUAL_EXTRA_FARE_UNIT = 5; + private static final int MORE_THAN_EXTRA_FARE_UNIT = 8; + + @Override + public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + final int distance = result.getDistanceValue(); + + final int extraDistance = min(EXTRA_FARE_SEGMENT - NO_EXTRA_FARE_DISTANCE, distance - NO_EXTRA_FARE_DISTANCE); + final int moreThanExtraDistance = max(0, distance - EXTRA_FARE_SEGMENT); + + return fare + calculateFare(extraDistance, LESS_THAN_OR_EQUAL_EXTRA_FARE_UNIT) + + calculateFare(moreThanExtraDistance, MORE_THAN_EXTRA_FARE_UNIT); + } + + private int calculateFare(final int distance, final int unit) { + return calculateUnit(distance, unit) * EXTRA_FARE_BY_UNIT; + } + + private int calculateUnit(final int distance, final int unit) { + return (int) Math.ceil(distance / (double) unit); + } +} diff --git a/src/main/java/subway/domain/fare/FarePolicy.java b/src/main/java/subway/domain/fare/FarePolicy.java new file mode 100644 index 000000000..9fb6c3c30 --- /dev/null +++ b/src/main/java/subway/domain/fare/FarePolicy.java @@ -0,0 +1,8 @@ +package subway.domain.fare; + +import subway.domain.path.PathFindResult; + +public interface FarePolicy { + + int calculate(final PathFindResult result, final Passenger passenger, final int fare); +} diff --git a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java new file mode 100644 index 000000000..95f7f5a97 --- /dev/null +++ b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java @@ -0,0 +1,29 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Distance; +import subway.domain.path.PathFindResult; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class BaseFarePolicyTest { + + @Test + void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›์„_๋”ํ•œ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final FarePolicy baseFarePolicy = new BaseFarePolicy(); + final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); + final Passenger passenger = new Passenger(); + + // when + final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); + + // then + assertThat(result).isEqualTo(1250); + } +} diff --git a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java new file mode 100644 index 000000000..94120917a --- /dev/null +++ b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java @@ -0,0 +1,56 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Distance; +import subway.domain.path.PathFindResult; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class DistanceFarePolicyTest { + + private FarePolicy farePolicy = new DistanceFarePolicy(); + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_๋ฐœ์ƒํ•˜์ง€_์•Š๋Š”๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); + final Passenger passenger = new Passenger(); + + // when + final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + + // then + assertThat(result).usingRecursiveComparison().isEqualTo(1250); + } + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๊ณ _50ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_5KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(27), Collections.emptyList()); + final Passenger passenger = new Passenger(); + + // when + final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + + // then + assertThat(result).isEqualTo(1650); + } + + @Test + void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_50ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_8KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(61), Collections.emptyList()); + final Passenger passenger = new Passenger(); + + // when + final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + + // then + assertThat(result).isEqualTo(2250); + } +} From ffb0fba4327b0193510f94e633c071724a1ae897 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 16:45:48 +0900 Subject: [PATCH 14/38] =?UTF-8?q?feat:=20=EB=85=B8=EC=84=A0=20=EB=B3=84=20?= =?UTF-8?q?=EC=9A=B4=EC=9E=84=20=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/domain/fare/BaseFarePolicy.java | 12 +++++++++- .../domain/fare/BaseFarePolicyTest.java | 24 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/subway/domain/fare/BaseFarePolicy.java b/src/main/java/subway/domain/fare/BaseFarePolicy.java index c3d867286..028d03952 100644 --- a/src/main/java/subway/domain/fare/BaseFarePolicy.java +++ b/src/main/java/subway/domain/fare/BaseFarePolicy.java @@ -1,6 +1,9 @@ package subway.domain.fare; +import java.util.Comparator; +import java.util.List; import subway.domain.path.PathFindResult; +import subway.domain.path.SectionEdge; public class BaseFarePolicy implements FarePolicy { @@ -8,6 +11,13 @@ public class BaseFarePolicy implements FarePolicy { @Override public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { - return fare + BASE_AMOUNT; + return fare + BASE_AMOUNT + calculateMaxSurcharge(result.getPath()); + } + + private int calculateMaxSurcharge(final List path) { + return path.stream() + .map(SectionEdge::getSurcharge) + .max(Comparator.naturalOrder()) + .orElse(0); } } diff --git a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java index 95f7f5a97..3d53dbbab 100644 --- a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java @@ -3,20 +3,24 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; import subway.domain.core.Distance; +import subway.domain.core.Section; import subway.domain.path.PathFindResult; +import subway.domain.path.SectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") class BaseFarePolicyTest { + final FarePolicy baseFarePolicy = new BaseFarePolicy(); + @Test void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›์„_๋”ํ•œ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final FarePolicy baseFarePolicy = new BaseFarePolicy(); final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); final Passenger passenger = new Passenger(); @@ -26,4 +30,22 @@ class BaseFarePolicyTest { // then assertThat(result).isEqualTo(1250); } + + @Test + void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›๊ณผ_๋…ธ์„ ์šด์ž„_์ค‘_๊ฐ€์žฅ๋†’์€_๊ฐ’์„_๋”ํ•˜์—ฌ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(9), List.of( + new SectionEdge(new Section("A", "B", 5), 100, 1), + new SectionEdge(new Section("B", "C", 10), 100, 1), + new SectionEdge(new Section("C", "T", 10), 300, 2), + new SectionEdge(new Section("T", "D", 10), 100, 1) + )); + final Passenger passenger = new Passenger(); + + // when + final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); + + // then + assertThat(result).isEqualTo(1550); + } } From 6577ddc8ef7940760efd238a85b1a83f9d1acd3d Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 16:58:21 +0900 Subject: [PATCH 15/38] =?UTF-8?q?feat:=20=EC=97=B0=EB=A0=B9=EB=8C=80=20Enu?= =?UTF-8?q?m=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/subway/domain/fare/AgeGroup.java | 21 ++++++++ .../java/subway/domain/fare/AgeGroupTest.java | 51 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/main/java/subway/domain/fare/AgeGroup.java create mode 100644 src/test/java/subway/domain/fare/AgeGroupTest.java diff --git a/src/main/java/subway/domain/fare/AgeGroup.java b/src/main/java/subway/domain/fare/AgeGroup.java new file mode 100644 index 000000000..79fd98e58 --- /dev/null +++ b/src/main/java/subway/domain/fare/AgeGroup.java @@ -0,0 +1,21 @@ +package subway.domain.fare; + +public enum AgeGroup { + ADULT(0, 0), + YOUTH(350, 0.2), + CHILD(350, 0.5), + ; + + private final int discountFare; + private final double discountRatio; + + AgeGroup(final int discountFare, final double discountRatio) { + this.discountFare = discountFare; + this.discountRatio = discountRatio; + } + + public int calculate(final int fare) { + final int result = fare - discountFare; + return (int) (result - result * discountRatio); + } +} diff --git a/src/test/java/subway/domain/fare/AgeGroupTest.java b/src/test/java/subway/domain/fare/AgeGroupTest.java new file mode 100644 index 000000000..b41fe7bbe --- /dev/null +++ b/src/test/java/subway/domain/fare/AgeGroupTest.java @@ -0,0 +1,51 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; +import static subway.domain.fare.AgeGroup.ADULT; +import static subway.domain.fare.AgeGroup.CHILD; +import static subway.domain.fare.AgeGroup.YOUTH; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AgeGroupTest { + + @Test + void ์„ฑ์ธ์˜_๊ฒฝ์šฐ_ํ• ์ธ์ด_์ ์šฉ๋˜์ง€_์•Š๋Š”๋‹ค() { + // given + final int fare = 1250; + + // when + final int result = ADULT.calculate(fare); + + // then + assertThat(result).isEqualTo(1250); + } + + @Test + void ์ฒญ์†Œ๋…„์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_20ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { + // given + final int fare = 1250; + + // when + final int result = YOUTH.calculate(fare); + + // then + assertThat(result).isEqualTo(720); + } + + @Test + void ์–ด๋ฆฐ์ด์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_50ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { + // given + final int fare = 1250; + + // when + final int result = CHILD.calculate(fare); + + // then + assertThat(result).isEqualTo(450); + } +} From d32bb52dde7cbf33fea6b86dc066dab9de4c5329 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 17:11:38 +0900 Subject: [PATCH 16/38] =?UTF-8?q?feat:=20=EC=97=B0=EB=A0=B9=EB=8C=80=20Enu?= =?UTF-8?q?m=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=EC=A0=95=EC=A0=81?= =?UTF-8?q?=20=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/subway/domain/fare/AgeGroup.java | 25 ++++++++--- .../java/subway/domain/fare/Passenger.java | 14 ++++++ .../subway/exception/InvalidAgeException.java | 8 ++++ .../java/subway/domain/fare/AgeGroupTest.java | 45 +++++++++++++++++-- .../domain/fare/BaseFarePolicyTest.java | 4 +- .../domain/fare/DistanceFarePolicyTest.java | 6 +-- 6 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 src/main/java/subway/domain/fare/Passenger.java create mode 100644 src/main/java/subway/exception/InvalidAgeException.java diff --git a/src/main/java/subway/domain/fare/AgeGroup.java b/src/main/java/subway/domain/fare/AgeGroup.java index 79fd98e58..f863c2e45 100644 --- a/src/main/java/subway/domain/fare/AgeGroup.java +++ b/src/main/java/subway/domain/fare/AgeGroup.java @@ -1,20 +1,35 @@ package subway.domain.fare; +import java.util.Arrays; +import subway.exception.InvalidAgeException; + public enum AgeGroup { - ADULT(0, 0), - YOUTH(350, 0.2), - CHILD(350, 0.5), + ADULT(19, Integer.MAX_VALUE, 0, 0), + YOUTH(13, 18, 350, 0.2), + CHILD(6, 12, 350, 0.5), + BABY(0, 5, 0, 1.0), ; + private final int minAge; + private final int maxAge; private final int discountFare; private final double discountRatio; - AgeGroup(final int discountFare, final double discountRatio) { + AgeGroup(final int minAge, final int maxAge, final int discountFare, final double discountRatio) { + this.minAge = minAge; + this.maxAge = maxAge; this.discountFare = discountFare; this.discountRatio = discountRatio; } - public int calculate(final int fare) { + public static AgeGroup from(final int age) { + return Arrays.stream(values()) + .filter(ageGroup -> ageGroup.minAge <= age && age <= ageGroup.maxAge) + .findFirst() + .orElseThrow(InvalidAgeException::new); + } + + public int calculateFare(final int fare) { final int result = fare - discountFare; return (int) (result - result * discountRatio); } diff --git a/src/main/java/subway/domain/fare/Passenger.java b/src/main/java/subway/domain/fare/Passenger.java new file mode 100644 index 000000000..60c668d3f --- /dev/null +++ b/src/main/java/subway/domain/fare/Passenger.java @@ -0,0 +1,14 @@ +package subway.domain.fare; + +public class Passenger { + + private AgeGroup ageGroup; + + public Passenger(final int age) { + this.ageGroup = AgeGroup.from(age); + } + + public int calculateFare(final int fare) { + return ageGroup.calculateFare(fare); + } +} diff --git a/src/main/java/subway/exception/InvalidAgeException.java b/src/main/java/subway/exception/InvalidAgeException.java new file mode 100644 index 000000000..cef13d50f --- /dev/null +++ b/src/main/java/subway/exception/InvalidAgeException.java @@ -0,0 +1,8 @@ +package subway.exception; + +public class InvalidAgeException extends SubwayException { + + public InvalidAgeException() { + super("์˜ฌ๋ฐ”๋ฅธ ๋‚˜์ด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค."); + } +} diff --git a/src/test/java/subway/domain/fare/AgeGroupTest.java b/src/test/java/subway/domain/fare/AgeGroupTest.java index b41fe7bbe..de24c4447 100644 --- a/src/test/java/subway/domain/fare/AgeGroupTest.java +++ b/src/test/java/subway/domain/fare/AgeGroupTest.java @@ -1,25 +1,52 @@ package subway.domain.fare; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static subway.domain.fare.AgeGroup.ADULT; +import static subway.domain.fare.AgeGroup.BABY; import static subway.domain.fare.AgeGroup.CHILD; import static subway.domain.fare.AgeGroup.YOUTH; +import static subway.domain.fare.AgeGroup.from; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import subway.exception.InvalidAgeException; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") class AgeGroupTest { + @Test + void ์˜ฌ๋ฐ”๋ฅธ_๋‚˜์ด๊ฐ€_์•„๋‹Œ_๊ฒฝ์šฐ_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + assertThatThrownBy(() -> from(-1)) + .isInstanceOf(InvalidAgeException.class) + .hasMessage("์˜ฌ๋ฐ”๋ฅธ ๋‚˜์ด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค."); + } + + @CsvSource({ + "0, BABY", + "5, BABY", + "6, CHILD", + "12, CHILD", + "13, YOUTH", + "18, YOUTH", + "19, ADULT", + }) + @ParameterizedTest(name = "{0}์ธ ๊ฒฝ์šฐ {1}์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค") + void ์˜ฌ๋ฐ”๋ฅธ_๋‚˜์ด์ธ_๊ฒฝ์šฐ_ํ•ด๋‹น_๋‚˜์ด์—_๋งž๋Š”_๊ทธ๋ฃน์„_๋ฐ˜ํ™˜ํ•œ๋‹ค(final int age, final AgeGroup group) { + assertThat(from(age)).isEqualTo(group); + } + @Test void ์„ฑ์ธ์˜_๊ฒฝ์šฐ_ํ• ์ธ์ด_์ ์šฉ๋˜์ง€_์•Š๋Š”๋‹ค() { // given final int fare = 1250; // when - final int result = ADULT.calculate(fare); + final int result = ADULT.calculateFare(fare); // then assertThat(result).isEqualTo(1250); @@ -31,7 +58,7 @@ class AgeGroupTest { final int fare = 1250; // when - final int result = YOUTH.calculate(fare); + final int result = YOUTH.calculateFare(fare); // then assertThat(result).isEqualTo(720); @@ -43,9 +70,21 @@ class AgeGroupTest { final int fare = 1250; // when - final int result = CHILD.calculate(fare); + final int result = CHILD.calculateFare(fare); // then assertThat(result).isEqualTo(450); } + + @Test + void ์œ ์•„์˜_๊ฒฝ์šฐ_๋ฌด๋ฃŒ๋‹ค() { + // given + final int fare = 1250; + + // when + final int result = BABY.calculateFare(fare); + + // then + assertThat(result).isZero(); + } } diff --git a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java index 3d53dbbab..f1b1b7928 100644 --- a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java @@ -22,7 +22,7 @@ class BaseFarePolicyTest { void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›์„_๋”ํ•œ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); - final Passenger passenger = new Passenger(); + final Passenger passenger = new Passenger(20); // when final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); @@ -40,7 +40,7 @@ class BaseFarePolicyTest { new SectionEdge(new Section("C", "T", 10), 300, 2), new SectionEdge(new Section("T", "D", 10), 100, 1) )); - final Passenger passenger = new Passenger(); + final Passenger passenger = new Passenger(20); // when final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); diff --git a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java index 94120917a..1e7b191b0 100644 --- a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java @@ -19,7 +19,7 @@ class DistanceFarePolicyTest { void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_๋ฐœ์ƒํ•˜์ง€_์•Š๋Š”๋‹ค() { // given final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); - final Passenger passenger = new Passenger(); + final Passenger passenger = new Passenger(20); // when final int result = farePolicy.calculate(pathFindResult, passenger, 1250); @@ -32,7 +32,7 @@ class DistanceFarePolicyTest { void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๊ณ _50ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_5KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given final PathFindResult pathFindResult = new PathFindResult(new Distance(27), Collections.emptyList()); - final Passenger passenger = new Passenger(); + final Passenger passenger = new Passenger(20); // when final int result = farePolicy.calculate(pathFindResult, passenger, 1250); @@ -45,7 +45,7 @@ class DistanceFarePolicyTest { void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_50ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_8KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given final PathFindResult pathFindResult = new PathFindResult(new Distance(61), Collections.emptyList()); - final Passenger passenger = new Passenger(); + final Passenger passenger = new Passenger(20); // when final int result = farePolicy.calculate(pathFindResult, passenger, 1250); From b308581e52f311168e146f91f6418e9a0450f4e3 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 17:36:58 +0900 Subject: [PATCH 17/38] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EB=82=98=EC=9D=B4=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EC=9D=84=20=ED=95=A0=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=A0=95=EC=B1=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/fare/AgeDiscountFarePolicy.java | 11 +++++++ .../fare/AgeDiscountFarePolicyTest.java | 31 +++++++++++++++++++ .../subway/domain/fare/PassengerTest.java | 25 +++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java create mode 100644 src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java create mode 100644 src/test/java/subway/domain/fare/PassengerTest.java diff --git a/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java new file mode 100644 index 000000000..ef642caed --- /dev/null +++ b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java @@ -0,0 +1,11 @@ +package subway.domain.fare; + +import subway.domain.path.PathFindResult; + +public class AgeDiscountFarePolicy implements FarePolicy { + + @Override + public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + return passenger.calculateFare(fare); + } +} diff --git a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java new file mode 100644 index 000000000..caa14d5a9 --- /dev/null +++ b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java @@ -0,0 +1,31 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Distance; +import subway.domain.path.PathFindResult; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class AgeDiscountFarePolicyTest { + + private FarePolicy farePolicy = new AgeDiscountFarePolicy(); + + @Test + void ๋‚˜์ด์—_๋”ฐ๋ผ_๊ธˆ์•ก์„_๊ณ„์‚ฐํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(5), Collections.emptyList()); + final Passenger passenger = new Passenger(17); + final int fare = 1250; + + // when + final int result = farePolicy.calculate(pathFindResult, passenger, fare); + + // then + assertThat(result).isEqualTo(720); + } +} diff --git a/src/test/java/subway/domain/fare/PassengerTest.java b/src/test/java/subway/domain/fare/PassengerTest.java new file mode 100644 index 000000000..f5ced453e --- /dev/null +++ b/src/test/java/subway/domain/fare/PassengerTest.java @@ -0,0 +1,25 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class PassengerTest { + + @Test + void ๋‚˜์ด์—_๋”ฐ๋ผ_๊ธˆ์•ก์„_๊ณ„์‚ฐํ•œ๋‹ค() { + // given + final Passenger passenger = new Passenger(17); + final int fare = 1250; + + // when + final int result = passenger.calculateFare(fare); + + // then + assertThat(result).isEqualTo(720); + } +} From cbfdbe238a24f4a0ed7fe796db90f4a891325c83 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 17:43:25 +0900 Subject: [PATCH 18/38] =?UTF-8?q?feat:=20=EC=B5=9C=EC=A2=85=20=EC=9A=B4?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EA=B3=84=EC=82=B0=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/subway/config/FareConfiguration.java | 23 +++++++++++ .../subway/domain/fare/SubwayFarePolicy.java | 22 ++++++++++ .../domain/fare/SubwayFarePolicyTest.java | 41 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/main/java/subway/config/FareConfiguration.java create mode 100644 src/main/java/subway/domain/fare/SubwayFarePolicy.java create mode 100644 src/test/java/subway/domain/fare/SubwayFarePolicyTest.java diff --git a/src/main/java/subway/config/FareConfiguration.java b/src/main/java/subway/config/FareConfiguration.java new file mode 100644 index 000000000..f628df866 --- /dev/null +++ b/src/main/java/subway/config/FareConfiguration.java @@ -0,0 +1,23 @@ +package subway.config; + +import java.util.List; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import subway.domain.fare.AgeDiscountFarePolicy; +import subway.domain.fare.BaseFarePolicy; +import subway.domain.fare.DistanceFarePolicy; +import subway.domain.fare.FarePolicy; +import subway.domain.fare.SubwayFarePolicy; + +@Configuration +public class FareConfiguration { + + @Bean + public FarePolicy farePolicy() { + return new SubwayFarePolicy(List.of( + new BaseFarePolicy(), + new DistanceFarePolicy(), + new AgeDiscountFarePolicy() + )); + } +} diff --git a/src/main/java/subway/domain/fare/SubwayFarePolicy.java b/src/main/java/subway/domain/fare/SubwayFarePolicy.java new file mode 100644 index 000000000..aa332bdc8 --- /dev/null +++ b/src/main/java/subway/domain/fare/SubwayFarePolicy.java @@ -0,0 +1,22 @@ +package subway.domain.fare; + +import java.util.List; +import subway.domain.path.PathFindResult; + +public class SubwayFarePolicy implements FarePolicy { + + private final List farePolicies; + + public SubwayFarePolicy(final List farePolicies) { + this.farePolicies = farePolicies; + } + + @Override + public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + int calculatedFare = fare; + for (FarePolicy farePolicy : farePolicies) { + calculatedFare = farePolicy.calculate(result, passenger, calculatedFare); + } + return calculatedFare; + } +} diff --git a/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java new file mode 100644 index 000000000..5f418aa9c --- /dev/null +++ b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java @@ -0,0 +1,41 @@ +package subway.domain.fare; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Distance; +import subway.domain.core.Section; +import subway.domain.path.PathFindResult; +import subway.domain.path.SectionEdge; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class SubwayFarePolicyTest { + + private FarePolicy farePolicy = new SubwayFarePolicy(List.of( + new BaseFarePolicy(), + new DistanceFarePolicy(), + new AgeDiscountFarePolicy() + )); + + @Test + void ์ตœ์ข…_์šด์ž„์„_๊ณ„์‚ฐํ•œ๋‹ค() { + // given + final PathFindResult pathFindResult = new PathFindResult(new Distance(35), List.of( + new SectionEdge(new Section("A", "B", 5), 300, 1), + new SectionEdge(new Section("B", "C", 10), 300, 1), + new SectionEdge(new Section("C", "T", 10), 500, 2), + new SectionEdge(new Section("T", "D", 10), 300, 1) + )); + final Passenger passenger = new Passenger(17); + + // when + final int result = farePolicy.calculate(pathFindResult, passenger, 0); + + // then + assertThat(result).isEqualTo(1520); + } +} From 2ba154fa237d8f2abdcf69d2f6f9d7dc4b533865 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:37:05 +0900 Subject: [PATCH 19/38] =?UTF-8?q?refactor:=205=EC=9D=B4=ED=95=98=EC=9D=98?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20=EC=9E=98=EB=AA=BB=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=EB=90=98=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/fare/DistanceFarePolicy.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/subway/domain/fare/DistanceFarePolicy.java b/src/main/java/subway/domain/fare/DistanceFarePolicy.java index fdf5ee8bc..9aafdfab7 100644 --- a/src/main/java/subway/domain/fare/DistanceFarePolicy.java +++ b/src/main/java/subway/domain/fare/DistanceFarePolicy.java @@ -17,7 +17,10 @@ public class DistanceFarePolicy implements FarePolicy { public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { final int distance = result.getDistanceValue(); - final int extraDistance = min(EXTRA_FARE_SEGMENT - NO_EXTRA_FARE_DISTANCE, distance - NO_EXTRA_FARE_DISTANCE); + final int extraDistance = min( + EXTRA_FARE_SEGMENT - NO_EXTRA_FARE_DISTANCE, + max(0, distance - NO_EXTRA_FARE_DISTANCE) + ); final int moreThanExtraDistance = max(0, distance - EXTRA_FARE_SEGMENT); return fare + calculateFare(extraDistance, LESS_THAN_OR_EQUAL_EXTRA_FARE_UNIT) + From 7e7649b4fb5abfa0a6830471975c3e189aef3f88 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:37:22 +0900 Subject: [PATCH 20/38] =?UTF-8?q?docs:=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http-request.http | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/http-request.http b/http-request.http index c06473106..f5efbd3a7 100644 --- a/http-request.http +++ b/http-request.http @@ -67,3 +67,14 @@ Content-Type: application/json "lineName": "1ํ˜ธ์„ ", "stationName": "B" } + +### ๊ธธ์ฐพ๊ธฐ + +POST http://localhost:8080/shortest-path +Content-Type: application/json + +{ + "start": "C", + "end": "A", + "age": 19 +} From 1d57a55b71ae99a1687dd6b6853cabdc21ec5302 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:37:53 +0900 Subject: [PATCH 21/38] =?UTF-8?q?remove:=20=EA=B2=BD=EB=A1=9C=20=EC=83=81?= =?UTF-8?q?=EC=9D=98=20=EA=B5=AC=EA=B0=84=EC=9D=84=20=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/domain/path/PathFindResult.java | 18 -------- .../domain/path/PathFindResultTest.java | 43 ------------------- 2 files changed, 61 deletions(-) delete mode 100644 src/test/java/subway/domain/path/PathFindResultTest.java diff --git a/src/main/java/subway/domain/path/PathFindResult.java b/src/main/java/subway/domain/path/PathFindResult.java index 9a7eb6219..10f4875a3 100644 --- a/src/main/java/subway/domain/path/PathFindResult.java +++ b/src/main/java/subway/domain/path/PathFindResult.java @@ -1,9 +1,7 @@ package subway.domain.path; -import java.util.ArrayList; import java.util.List; import subway.domain.core.Distance; -import subway.domain.core.Section; public class PathFindResult { @@ -15,22 +13,6 @@ public PathFindResult(final Distance distance, final List path) { this.path = path; } - public List> toSections() { - final List> result = new ArrayList<>(); - - List
currentLine = new ArrayList<>(); - long currentLineId = 0; - for (SectionEdge sectionEdge : path) { - if (currentLine.isEmpty() || currentLineId != sectionEdge.getLineId()) { - currentLine = new ArrayList<>(); - currentLineId = sectionEdge.getLineId(); - result.add(currentLine); - } - currentLine.add(sectionEdge.toSection()); - } - return result; - } - public int getDistanceValue() { return distance.getValue(); } diff --git a/src/test/java/subway/domain/path/PathFindResultTest.java b/src/test/java/subway/domain/path/PathFindResultTest.java deleted file mode 100644 index b174e199b..000000000 --- a/src/test/java/subway/domain/path/PathFindResultTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package subway.domain.path; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; -import subway.domain.core.Distance; -import subway.domain.core.Section; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -@SuppressWarnings("NonAsciiCharacters") -class PathFindResultTest { - - @Test - void ๊ฒฝ๋กœ_์ƒ์˜_๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ผ์ธ_๊ธฐ์ค€์œผ๋กœ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { - // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(5), List.of( - new SectionEdge(new Section("A", "B", 5), 500, 1), - new SectionEdge(new Section("B", "C", 10), 500, 1), - new SectionEdge(new Section("C", "T", 10), 500, 2), - new SectionEdge(new Section("T", "D", 10), 500, 1) - )); - - // when - final List> result = pathFindResult.toSections(); - - // then - assertThat(result).usingRecursiveComparison().ignoringExpectedNullFields().isEqualTo(List.of( - List.of( - new Section("A", "B", 5), - new Section("B", "C", 10) - ), - List.of( - new Section("C", "T", 10) - ), - List.of( - new Section("T", "D", 10) - ) - )); - } -} From 8156ed269cc25a44f9c60faaa39a35a45f400a98 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:38:10 +0900 Subject: [PATCH 22/38] =?UTF-8?q?test:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/subway/domain/path/PathFinderTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/domain/path/PathFinderTest.java index b98474d97..f8edcf4cc 100644 --- a/src/test/java/subway/domain/path/PathFinderTest.java +++ b/src/test/java/subway/domain/path/PathFinderTest.java @@ -19,11 +19,11 @@ class PathFinderTest { void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_ํƒ์ƒ‰ํ•œ๋‹ค() { // given final Subway subway = new Subway(List.of( - new Line("1ํ˜ธ์„ ", "RED", 0, List.of( + new Line(1L, "1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2), new Section("B", "C", 3) )), - new Line("2ํ˜ธ์„ ", "RED", 0, List.of( + new Line(2L, "2ํ˜ธ์„ ", "RED", 300, List.of( new Section("Z", "B", 4), new Section("B", "Y", 5) )) @@ -37,6 +37,7 @@ class PathFinderTest { assertAll( () -> assertThat(pathFindResult.getDistanceValue()).isEqualTo(7), () -> assertThat(pathFindResult.getPath()) + .extracting(SectionEdge::toSection) .usingRecursiveComparison() .ignoringExpectedNullFields() .isEqualTo(List.of( From ba52a5c6fdeb6c5ca94d35c391a6021c35237ea7 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:38:25 +0900 Subject: [PATCH 23/38] =?UTF-8?q?remove:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/core/Subway.java | 6 ----- .../java/subway/domain/path/SectionEdge.java | 9 -------- .../java/subway/domain/core/SubwayTest.java | 23 ------------------- 3 files changed, 38 deletions(-) diff --git a/src/main/java/subway/domain/core/Subway.java b/src/main/java/subway/domain/core/Subway.java index 3895eb725..8280ded5f 100644 --- a/src/main/java/subway/domain/core/Subway.java +++ b/src/main/java/subway/domain/core/Subway.java @@ -76,12 +76,6 @@ public Station findStationByName(final String name) { .orElseThrow(StationNotFoundException::new); } - public List
getSections() { - return lines.stream() - .flatMap(line -> line.getSections().stream()) - .collect(toList()); - } - public List getStations() { return lines.stream() .flatMap(line -> line.findAllStation().stream()) diff --git a/src/main/java/subway/domain/path/SectionEdge.java b/src/main/java/subway/domain/path/SectionEdge.java index 5d00cc7d4..dd51dbcc3 100644 --- a/src/main/java/subway/domain/path/SectionEdge.java +++ b/src/main/java/subway/domain/path/SectionEdge.java @@ -26,13 +26,4 @@ public int getSurcharge() { public long getLineId() { return lineId; } - - @Override - public String toString() { - return "SectionEdge{" + - "section=" + section + - ", surcharge=" + surcharge + - ", lineId=" + lineId + - '}'; - } } diff --git a/src/test/java/subway/domain/core/SubwayTest.java b/src/test/java/subway/domain/core/SubwayTest.java index 9349e8bf2..a9e8dd011 100644 --- a/src/test/java/subway/domain/core/SubwayTest.java +++ b/src/test/java/subway/domain/core/SubwayTest.java @@ -204,29 +204,6 @@ class SubwayTest { assertThat(result.getName()).isEqualTo("A"); } - @Test - void ๋ชจ๋“ _๊ตฌ๊ฐ„์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { - // given - final Subway subway = new Subway(List.of( - new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( - new Section("A", "B", 3), - new Section("B", "C", 5)) - ) - )); - - // when - final List
result = subway.getSections(); - - // then - assertThat(result) - .usingRecursiveComparison() - .ignoringExpectedNullFields() - .isEqualTo(List.of( - new Section("A", "B", 3), - new Section("B", "C", 5)) - ); - } - @Test void ๋ชจ๋“ _์—ญ์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given From b4c0e530c23a351099ea587c51f0ec16a75b1543 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Wed, 17 May 2023 23:52:30 +0900 Subject: [PATCH 24/38] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/dto/LineDto.java | 24 ++++++ src/main/java/subway/dto/SectionDto.java | 32 ++++++++ .../java/subway/dto/ShortestPathRequest.java | 34 ++++++++ .../java/subway/dto/ShortestPathResponse.java | 28 +++++++ .../exception/GlobalExceptionHandler.java | 7 ++ src/main/java/subway/service/PathService.java | 58 +++++++++++++ .../java/subway/service/PathServiceTest.java | 82 +++++++++++++++++++ 7 files changed, 265 insertions(+) create mode 100644 src/main/java/subway/dto/LineDto.java create mode 100644 src/main/java/subway/dto/SectionDto.java create mode 100644 src/main/java/subway/dto/ShortestPathRequest.java create mode 100644 src/main/java/subway/dto/ShortestPathResponse.java create mode 100644 src/main/java/subway/service/PathService.java create mode 100644 src/test/java/subway/service/PathServiceTest.java diff --git a/src/main/java/subway/dto/LineDto.java b/src/main/java/subway/dto/LineDto.java new file mode 100644 index 000000000..ebccdf45d --- /dev/null +++ b/src/main/java/subway/dto/LineDto.java @@ -0,0 +1,24 @@ +package subway.dto; + +import java.util.List; + +public class LineDto { + + private final String name; + private final String color; + private final List sections; + + public LineDto(final String name, final String color, final List sections) { + this.name = name; + this.color = color; + this.sections = sections; + } + + public String getName() { + return name; + } + + public List getSections() { + return sections; + } +} diff --git a/src/main/java/subway/dto/SectionDto.java b/src/main/java/subway/dto/SectionDto.java new file mode 100644 index 000000000..9f5cfd975 --- /dev/null +++ b/src/main/java/subway/dto/SectionDto.java @@ -0,0 +1,32 @@ +package subway.dto; + +import subway.domain.core.Section; + +public class SectionDto { + + private final String start; + private final String end; + private final int distance; + + public SectionDto(final String start, final String end, final int distance) { + this.start = start; + this.end = end; + this.distance = distance; + } + + public static SectionDto from(final Section section) { + return new SectionDto(section.getStartName(), section.getEndName(), section.getDistanceValue()); + } + + public String getStart() { + return start; + } + + public String getEnd() { + return end; + } + + public int getDistance() { + return distance; + } +} diff --git a/src/main/java/subway/dto/ShortestPathRequest.java b/src/main/java/subway/dto/ShortestPathRequest.java new file mode 100644 index 000000000..4f2d1bfc6 --- /dev/null +++ b/src/main/java/subway/dto/ShortestPathRequest.java @@ -0,0 +1,34 @@ +package subway.dto; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.PositiveOrZero; + +public class ShortestPathRequest { + + @NotBlank(message = "์‹œ์ž‘์—ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String start; + + @NotBlank(message = "๋„์ฐฉ์—ญ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private final String end; + + @PositiveOrZero(message = "๋‚˜์ด๋Š” 0์‚ด ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private final Integer age; + + public ShortestPathRequest(final String start, final String end, final Integer age) { + this.start = start; + this.end = end; + this.age = age; + } + + public String getStart() { + return start; + } + + public String getEnd() { + return end; + } + + public Integer getAge() { + return age; + } +} diff --git a/src/main/java/subway/dto/ShortestPathResponse.java b/src/main/java/subway/dto/ShortestPathResponse.java new file mode 100644 index 000000000..3754ec994 --- /dev/null +++ b/src/main/java/subway/dto/ShortestPathResponse.java @@ -0,0 +1,28 @@ +package subway.dto; + +import java.util.List; + +public class ShortestPathResponse { + + private final List path; + private final int distance; + private final int fare; + + public ShortestPathResponse(final List path, final int distance, final int fare) { + this.path = path; + this.distance = distance; + this.fare = fare; + } + + public List getPath() { + return path; + } + + public int getDistance() { + return distance; + } + + public int getFare() { + return fare; + } +} diff --git a/src/main/java/subway/exception/GlobalExceptionHandler.java b/src/main/java/subway/exception/GlobalExceptionHandler.java index 9e29a88c1..0a3824168 100644 --- a/src/main/java/subway/exception/GlobalExceptionHandler.java +++ b/src/main/java/subway/exception/GlobalExceptionHandler.java @@ -25,6 +25,13 @@ public ResponseEntity handleException(final Exception e) { .body(new ExceptionResponse("์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")); } + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity handleIllegalArgumentException(final IllegalArgumentException e) { + logger.warn("WARN: ", e); + return ResponseEntity.badRequest() + .body(new ExceptionResponse("์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.")); + } + @ExceptionHandler(SubwayException.class) public ResponseEntity handleSubwayException(final SubwayException e) { logger.warn(e.getMessage()); diff --git a/src/main/java/subway/service/PathService.java b/src/main/java/subway/service/PathService.java new file mode 100644 index 000000000..3165e43cc --- /dev/null +++ b/src/main/java/subway/service/PathService.java @@ -0,0 +1,58 @@ +package subway.service; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Service; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Subway; +import subway.domain.fare.FarePolicy; +import subway.domain.fare.Passenger; +import subway.domain.path.PathFindResult; +import subway.domain.path.PathFinder; +import subway.domain.path.SectionEdge; +import subway.dto.LineDto; +import subway.dto.SectionDto; +import subway.dto.ShortestPathRequest; +import subway.dto.ShortestPathResponse; +import subway.exception.LineNotFoundException; +import subway.repository.LineRepository; + +@Service +public class PathService { + + private final LineRepository lineRepository; + private final FarePolicy farePolicy; + + public PathService(final LineRepository lineRepository, final FarePolicy farePolicy) { + this.lineRepository = lineRepository; + this.farePolicy = farePolicy; + } + + public ShortestPathResponse shortestPath(final ShortestPathRequest request) { + final Subway subway = new Subway(lineRepository.findAll()); + final PathFinder pathFinder = new PathFinder(subway); + final PathFindResult result = pathFinder.find(request.getStart(), request.getEnd()); + final int fare = farePolicy.calculate(result, new Passenger(request.getAge()), 0); + return new ShortestPathResponse(toLineDtos(result.getPath()), result.getDistanceValue(), fare); + } + + private List toLineDtos(final List path) { + final List result = new ArrayList<>(); + + List currentLine = new ArrayList<>(); + long currentLineId = 0; + for (SectionEdge sectionEdge : path) { + if (currentLine.isEmpty() || currentLineId != sectionEdge.getLineId()) { + currentLine = new ArrayList<>(); + currentLineId = sectionEdge.getLineId(); + final Line line = lineRepository.findById(sectionEdge.getLineId()) + .orElseThrow(LineNotFoundException::new); + result.add(new LineDto(line.getName(), line.getColor(), currentLine)); + } + final Section section = sectionEdge.toSection(); + currentLine.add(SectionDto.from(section)); + } + return result; + } +} diff --git a/src/test/java/subway/service/PathServiceTest.java b/src/test/java/subway/service/PathServiceTest.java new file mode 100644 index 000000000..173831443 --- /dev/null +++ b/src/test/java/subway/service/PathServiceTest.java @@ -0,0 +1,82 @@ +package subway.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.dto.LineDto; +import subway.dto.SectionDto; +import subway.dto.ShortestPathRequest; +import subway.dto.ShortestPathResponse; +import subway.repository.LineRepository; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@Transactional +@SpringBootTest +public class PathServiceTest { + + @Autowired + private PathService pathService; + + @Autowired + private LineRepository lineRepository; + + @Test + void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_ํƒ์ƒ‰ํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( + new Section("A", "B", 2), + new Section("B", "C", 100) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( + new Section("Z", "B", 2), + new Section("Y", "Z", 5), + new Section("C", "Y", 3) + ))); + + final ShortestPathRequest request = new ShortestPathRequest("C", "A", 15); + + // when + final ShortestPathResponse result = pathService.shortestPath(request); + + // then + assertAll( + () -> assertThat(result.getFare()).isEqualTo(800), + () -> assertThat(result.getDistance()).isEqualTo(12), + () -> assertThat(result.getPath()) + .usingRecursiveComparison() + .isEqualTo(List.of( + new LineDto( + "2ํ˜ธ์„ ", "BLUE", List.of( + new SectionDto("C", "Y", 3), + new SectionDto("Y", "Z", 5), + new SectionDto("Z", "B", 2) + )), + new LineDto( + "1ํ˜ธ์„ ", "RED", List.of( + new SectionDto("A", "B", 2) + )) + )) + ); + } + + @Test + void ์˜ฌ๋ฐ”๋ฅด์ง€_์•Š์€_์ถœ๋ฐœ์—ญ๊ณผ_๋„์ฐฉ์—ญ์„_์ž…๋ ฅํ•˜๋ฉด_์˜ˆ์™ธ๋ฅผ_๋˜์ง„๋‹ค() { + // given + final ShortestPathRequest request = new ShortestPathRequest("C", "A", 15); + + // expect + assertThatThrownBy(() -> pathService.shortestPath(request)) + .isInstanceOf(IllegalArgumentException.class); + } +} From decd8eb6caea88054682275cbf3093579ccd0701 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Thu, 18 May 2023 00:19:24 +0900 Subject: [PATCH 25/38] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/controller/PathController.java | 26 +++++++ src/main/java/subway/dto/LineDto.java | 4 + .../subway/controller/PathControllerTest.java | 73 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 src/main/java/subway/controller/PathController.java create mode 100644 src/test/java/subway/controller/PathControllerTest.java diff --git a/src/main/java/subway/controller/PathController.java b/src/main/java/subway/controller/PathController.java new file mode 100644 index 000000000..640570451 --- /dev/null +++ b/src/main/java/subway/controller/PathController.java @@ -0,0 +1,26 @@ +package subway.controller; + +import javax.validation.Valid; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import subway.dto.ShortestPathRequest; +import subway.dto.ShortestPathResponse; +import subway.service.PathService; + +@RestController +public class PathController { + + private final PathService pathService; + + public PathController(final PathService pathService) { + this.pathService = pathService; + } + + @PostMapping("/shortest-path") + public ResponseEntity shortestPath(@RequestBody @Valid final ShortestPathRequest request) { + final ShortestPathResponse response = pathService.shortestPath(request); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/subway/dto/LineDto.java b/src/main/java/subway/dto/LineDto.java index ebccdf45d..bd78fff1e 100644 --- a/src/main/java/subway/dto/LineDto.java +++ b/src/main/java/subway/dto/LineDto.java @@ -18,6 +18,10 @@ public String getName() { return name; } + public String getColor() { + return color; + } + public List getSections() { return sections; } diff --git a/src/test/java/subway/controller/PathControllerTest.java b/src/test/java/subway/controller/PathControllerTest.java new file mode 100644 index 000000000..35fd5b68d --- /dev/null +++ b/src/test/java/subway/controller/PathControllerTest.java @@ -0,0 +1,73 @@ +package subway.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import subway.common.IntegrationTest; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.dto.LineDto; +import subway.dto.SectionDto; +import subway.dto.ShortestPathRequest; +import subway.dto.ShortestPathResponse; +import subway.repository.LineRepository; + +public class PathControllerTest extends IntegrationTest { + + @Autowired + private LineRepository lineRepository; + + @Test + public void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_์กฐํšŒํ•œ๋‹ค() { + // given + lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( + new Section("A", "B", 2), + new Section("B", "C", 100) + ))); + lineRepository.save(new Line("2ํ˜ธ์„ ", "BLUE", 0, List.of( + new Section("Z", "B", 2), + new Section("Y", "Z", 5), + new Section("C", "Y", 3) + ))); + final ShortestPathRequest shortestPathRequest = new ShortestPathRequest("C", "A", 17); + + // when + ExtractableResponse response = RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(shortestPathRequest) + .when().post("/shortest-path") + .then().log().all() + .extract(); + + // then + assertAll( + () -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()), + () -> assertThat(response.jsonPath().getObject(".", ShortestPathResponse.class)) + .usingRecursiveComparison() + .ignoringExpectedNullFields() + .isEqualTo( + new ShortestPathResponse(List.of( + new LineDto( + "2ํ˜ธ์„ ", "BLUE", List.of( + new SectionDto("C", "Y", 3), + new SectionDto("Y", "Z", 5), + new SectionDto("Z", "B", 2) + )), + new LineDto( + "1ํ˜ธ์„ ", "RED", List.of( + new SectionDto("A", "B", 2) + )) + ), 12, 800) + ) + ); + } +} From 8ac02f2d9ea142b1ba066cb80e5d22e8819c373e Mon Sep 17 00:00:00 2001 From: greeng00se Date: Thu, 18 May 2023 00:39:25 +0900 Subject: [PATCH 26/38] =?UTF-8?q?test:=20=EA=B2=BD=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subway/acceptance/PathAcceptanceTest.java | 59 +++++++++++++++++++ .../java/subway/common/steps/PathSteps.java | 59 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 src/test/java/subway/acceptance/PathAcceptanceTest.java create mode 100644 src/test/java/subway/common/steps/PathSteps.java diff --git a/src/test/java/subway/acceptance/PathAcceptanceTest.java b/src/test/java/subway/acceptance/PathAcceptanceTest.java new file mode 100644 index 000000000..379834476 --- /dev/null +++ b/src/test/java/subway/acceptance/PathAcceptanceTest.java @@ -0,0 +1,59 @@ +package subway.acceptance; + +import static subway.common.steps.CommonSteps.์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค; +import static subway.common.steps.CommonSteps.์ •์ƒ_์š”์ฒญ; +import static subway.common.steps.LineSteps.๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.PathSteps.์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ; +import static subway.common.steps.PathSteps.์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค; +import static subway.common.steps.PathSteps.์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_์š”์ฒญ; +import static subway.common.steps.PathSteps.์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„; +import static subway.common.steps.SectionSteps.๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ; +import static subway.common.steps.SectionSteps.์˜ค๋ฅธ์ชฝ; + +import org.junit.jupiter.api.Test; +import subway.common.AcceptanceTest; + +@SuppressWarnings("NonAsciiCharacters") +public class PathAcceptanceTest extends AcceptanceTest { + + @Test + void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_์กฐํšŒํ•œ๋‹ค() { + // given + final var ์ดˆ๋ก์ƒ‰_2ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ดˆ๋ก", 0); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค", "์ž ์‹ค์ƒˆ๋‚ด", 2); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("2ํ˜ธ์„ ", "์ž ์‹ค์ƒˆ๋‚ด", "์ข…ํ•ฉ์šด๋™์žฅ", ์˜ค๋ฅธ์ชฝ, 100); + + final var ์ฃผํ™ฉ์ƒ‰_3ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๊ฐˆ์ƒ‰", 500); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "๋ด‰์€์‚ฌ", "์ข…ํ•ฉ์šด๋™์žฅ", 2); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „", ์˜ค๋ฅธ์ชฝ, 2); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "์‚ผ์ „", "์„์ดŒ๊ณ ๋ถ„", ์˜ค๋ฅธ์ชฝ, 2); + ๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("9ํ˜ธ์„ ", "์„์ดŒ๊ณ ๋ถ„", "์„์ดŒ", ์˜ค๋ฅธ์ชฝ, 2); + + final var ํ•‘ํฌ์ƒ‰_8ํ˜ธ์„  = ๋…ธ์„ _์ƒ์„ฑ_์š”์ฒญ("8ํ˜ธ์„ ", "ํ•‘ํฌ์ƒ‰", 1500); + ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ("8ํ˜ธ์„ ", "์ž ์‹ค", "์„์ดŒ", 1); + + // when + final var ์กฐํšŒ_์š”์ฒญ_๊ฒฐ๊ณผ = ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_์š”์ฒญ("์ž ์‹ค", "์ข…ํ•ฉ์šด๋™์žฅ", 15); + + // then + ์š”์ฒญ_๊ฒฐ๊ณผ์˜_์ƒํƒœ๋ฅผ_๊ฒ€์ฆํ•œ๋‹ค(์กฐํšŒ_์š”์ฒญ_๊ฒฐ๊ณผ, ์ •์ƒ_์š”์ฒญ); + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + ์กฐํšŒ_์š”์ฒญ_๊ฒฐ๊ณผ, + 7, + 1920, + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ( + "8ํ˜ธ์„ ", + "ํ•‘ํฌ์ƒ‰", + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„("์ž ์‹ค", "์„์ดŒ", 1) + ), + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ( + "9ํ˜ธ์„ ", + "๊ฐˆ์ƒ‰", + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„("์„์ดŒ๊ณ ๋ถ„", "์„์ดŒ", 2), + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„("์‚ผ์ „", "์„์ดŒ๊ณ ๋ถ„", 2), + ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„("์ข…ํ•ฉ์šด๋™์žฅ", "์‚ผ์ „", 2) + ) + ); + } +} diff --git a/src/test/java/subway/common/steps/PathSteps.java b/src/test/java/subway/common/steps/PathSteps.java new file mode 100644 index 000000000..57dc9433a --- /dev/null +++ b/src/test/java/subway/common/steps/PathSteps.java @@ -0,0 +1,59 @@ +package subway.common.steps; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.http.MediaType; +import subway.dto.LineDto; +import subway.dto.SectionDto; +import subway.dto.ShortestPathRequest; +import subway.dto.ShortestPathResponse; + +@SuppressWarnings("NonAsciiCharacters") +public class PathSteps { + + public static ExtractableResponse ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_์š”์ฒญ(final String ์‹œ์ž‘์—ญ, final String ๋„์ฐฉ์—ญ, final Integer ๋‚˜์ด) { + final ShortestPathRequest request = new ShortestPathRequest(์‹œ์ž‘์—ญ, ๋„์ฐฉ์—ญ, ๋‚˜์ด); + + return RestAssured + .given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(request) + .when().post("/shortest-path") + .then().log().all() + .extract(); + } + + public static void ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ_์กฐํšŒ_๊ฒฐ๊ณผ๋ฅผ_ํ™•์ธํ•œ๋‹ค( + final ExtractableResponse ์š”์ฒญ_๊ฒฐ๊ณผ, + final Integer ๊ฑฐ๋ฆฌ, + final Integer ์šด์ž„, + final LineDto... ๊ฒฝ๋กœ + ) { + final List ๊ฒฝ๋กœ_๋ชจ์Œ = Arrays.stream(๊ฒฝ๋กœ).collect(Collectors.toList()); + assertThat(์š”์ฒญ_๊ฒฐ๊ณผ.jsonPath().getObject(".", ShortestPathResponse.class)) + .usingRecursiveComparison() + .isEqualTo(new ShortestPathResponse(๊ฒฝ๋กœ_๋ชจ์Œ, ๊ฑฐ๋ฆฌ, ์šด์ž„)); + } + + public static LineDto ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ฒฝ๋กœ( + final String ๋…ธ์„ ๋ช…, + final String ๋…ธ์„ ์ƒ‰, + final SectionDto... ๊ตฌ๊ฐ„) { + final List ๊ตฌ๊ฐ„_๋ชจ์Œ = Arrays.stream(๊ตฌ๊ฐ„).collect(Collectors.toList()); + return new LineDto(๋…ธ์„ ๋ช…, ๋…ธ์„ ์ƒ‰, ๊ตฌ๊ฐ„_๋ชจ์Œ); + } + + public static SectionDto ์ตœ๋‹จ๊ฑฐ๋ฆฌ_๊ตฌ๊ฐ„( + final String ์ƒํ–‰์—ญ, + final String ํ•˜ํ–‰์—ญ, + final int ๊ฑฐ๋ฆฌ + ) { + return new SectionDto(์ƒํ–‰์—ญ, ํ•˜ํ–‰์—ญ, ๊ฑฐ๋ฆฌ); + } +} From b1f1b0874a793adf5008b3e2d352526482b65a05 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Thu, 18 May 2023 00:49:40 +0900 Subject: [PATCH 27/38] =?UTF-8?q?docs:=20README=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c74dc5450..326cb8bde 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ - [x] ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. - [x] ์ „์ฒด ๋…ธ์„  ์กฐํšŒ - [x] ์ „์ฒด ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค. -- [ ] ๊ฒฝ๋กœ ์กฐํšŒ - - [ ] ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. - - [ ] ์š”๊ธˆ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. +- [x] ๊ฒฝ๋กœ ์กฐํšŒ + - [x] ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. + - [x] ์š”๊ธˆ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. - ๊ธฐ๋ณธ์šด์ž„(10ใŽž ์ด๋‚ด): ๊ธฐ๋ณธ์šด์ž„ 1,250์› - ์ด์šฉ ๊ฑฐ๋ฆฌ ์ดˆ๊ณผ ์‹œ ์ถ”๊ฐ€์šด์ž„ ๋ถ€๊ณผ - 10km~50km: 5km ๊นŒ์ง€ ๋งˆ๋‹ค 100์› ์ถ”๊ฐ€ From 166ca4e4219b6e48f61888c22f3eca6bf95e4179 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Thu, 18 May 2023 01:18:30 +0900 Subject: [PATCH 28/38] =?UTF-8?q?feat:=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=EC=97=90=20Transactional=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/service/PathService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/subway/service/PathService.java b/src/main/java/subway/service/PathService.java index 3165e43cc..bd8179966 100644 --- a/src/main/java/subway/service/PathService.java +++ b/src/main/java/subway/service/PathService.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import subway.domain.core.Line; import subway.domain.core.Section; import subway.domain.core.Subway; @@ -18,6 +19,7 @@ import subway.exception.LineNotFoundException; import subway.repository.LineRepository; +@Transactional(readOnly = true) @Service public class PathService { From 46adac9c4bd2e5ac3271e8647f7ac44859b1722a Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 14:22:32 +0900 Subject: [PATCH 29/38] =?UTF-8?q?docs:=203=EB=8B=A8=EA=B3=84=20=EC=9A=94?= =?UTF-8?q?=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 326cb8bde..6413c0a89 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ - ์ด์šฉ ๊ฑฐ๋ฆฌ ์ดˆ๊ณผ ์‹œ ์ถ”๊ฐ€์šด์ž„ ๋ถ€๊ณผ - 10km~50km: 5km ๊นŒ์ง€ ๋งˆ๋‹ค 100์› ์ถ”๊ฐ€ - 50km ์ดˆ๊ณผ: 8km ๊นŒ์ง€ ๋งˆ๋‹ค 100์› ์ถ”๊ฐ€ + - ๋…ธ์„  ๋ณ„ ์ถ”๊ฐ€ ์šด์ž„์„ ๋ถ€๊ณผ + - ์ถ”๊ฐ€ ์šด์ž„์€ ๊ฐ€์žฅ ๋†’์€ ๊ธˆ์•ก์˜ ์ถ”๊ฐ€ ์š”๊ธˆ๋งŒ ์ ์šฉ๋œ๋‹ค. + - ์—ฐ๋ น ๋ณ„ ์š”๊ธˆ ํ• ์ธ + - ์ฒญ์†Œ๋…„(13์„ธ ์ด์ƒ 19์„ธ ๋ฏธ๋งŒ): 350์›์„ ๊ณต์ œํ•œ ๊ธˆ์•ก์—์„œ 20%๋ฅผ ํ• ์ธํ•œ๋‹ค. + - ์–ด๋ฆฐ์ด(6์„ธ ์ด์ƒ 13์„ธ ๋ฏธ๋งŒ): 350์›์„ ๊ณต์ œํ•œ ๊ธˆ์•ก์—์„œ 50%๋ฅผ ํ• ์ธํ•œ๋‹ค. ### ๐Ÿš‰ ์—ญ API From 7546b6a7063bbe180628306d2f3522376db07052 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 15:25:34 +0900 Subject: [PATCH 30/38] =?UTF-8?q?refactor:=20=EC=B5=9C=EB=8B=A8=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EA=B2=80=EC=83=89=20GET=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http-request.http | 8 +------- src/main/java/subway/controller/PathController.java | 8 ++++---- .../java/subway/exception/GlobalExceptionHandler.java | 6 +++--- src/test/java/subway/common/steps/PathSteps.java | 6 ++++-- src/test/java/subway/controller/PathControllerTest.java | 8 +++++--- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/http-request.http b/http-request.http index f5efbd3a7..7481b26e9 100644 --- a/http-request.http +++ b/http-request.http @@ -70,11 +70,5 @@ Content-Type: application/json ### ๊ธธ์ฐพ๊ธฐ -POST http://localhost:8080/shortest-path +GET http://localhost:8080/shortest-path?start=C&end=A&age=19 Content-Type: application/json - -{ - "start": "C", - "end": "A", - "age": 19 -} diff --git a/src/main/java/subway/controller/PathController.java b/src/main/java/subway/controller/PathController.java index 640570451..0565398de 100644 --- a/src/main/java/subway/controller/PathController.java +++ b/src/main/java/subway/controller/PathController.java @@ -2,8 +2,8 @@ import javax.validation.Valid; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RestController; import subway.dto.ShortestPathRequest; import subway.dto.ShortestPathResponse; @@ -18,8 +18,8 @@ public PathController(final PathService pathService) { this.pathService = pathService; } - @PostMapping("/shortest-path") - public ResponseEntity shortestPath(@RequestBody @Valid final ShortestPathRequest request) { + @GetMapping("/shortest-path") + public ResponseEntity shortestPath(@ModelAttribute @Valid final ShortestPathRequest request) { final ShortestPathResponse response = pathService.shortestPath(request); return ResponseEntity.ok(response); } diff --git a/src/main/java/subway/exception/GlobalExceptionHandler.java b/src/main/java/subway/exception/GlobalExceptionHandler.java index 0a3824168..39ab00897 100644 --- a/src/main/java/subway/exception/GlobalExceptionHandler.java +++ b/src/main/java/subway/exception/GlobalExceptionHandler.java @@ -6,7 +6,7 @@ import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import subway.dto.ExceptionResponse; @@ -46,8 +46,8 @@ public ResponseEntity handleLineNotFoundException(final LineN .body(new ExceptionResponse(e.getMessage())); } - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity handleValidException(final MethodArgumentNotValidException e) { + @ExceptionHandler(BindException.class) + public ResponseEntity handleBindException(final BindException e) { final String errorMessage = e.getFieldErrors().stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.joining(DELIMITER)); diff --git a/src/test/java/subway/common/steps/PathSteps.java b/src/test/java/subway/common/steps/PathSteps.java index 57dc9433a..9902e7f9c 100644 --- a/src/test/java/subway/common/steps/PathSteps.java +++ b/src/test/java/subway/common/steps/PathSteps.java @@ -23,8 +23,10 @@ public class PathSteps { return RestAssured .given().log().all() .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(request) - .when().post("/shortest-path") + .queryParam("start", request.getStart()) + .queryParam("end", request.getEnd()) + .queryParam("age", request.getAge()) + .when().get("/shortest-path") .then().log().all() .extract(); } diff --git a/src/test/java/subway/controller/PathControllerTest.java b/src/test/java/subway/controller/PathControllerTest.java index 35fd5b68d..0017c735e 100644 --- a/src/test/java/subway/controller/PathControllerTest.java +++ b/src/test/java/subway/controller/PathControllerTest.java @@ -37,14 +37,16 @@ public class PathControllerTest extends IntegrationTest { new Section("Y", "Z", 5), new Section("C", "Y", 3) ))); - final ShortestPathRequest shortestPathRequest = new ShortestPathRequest("C", "A", 17); + final ShortestPathRequest request = new ShortestPathRequest("C", "A", 17); // when ExtractableResponse response = RestAssured .given().log().all() .contentType(MediaType.APPLICATION_JSON_VALUE) - .body(shortestPathRequest) - .when().post("/shortest-path") + .queryParam("start", request.getStart()) + .queryParam("end", request.getEnd()) + .queryParam("age", request.getAge()) + .when().get("/shortest-path") .then().log().all() .extract(); From c485eccc7a81a132a6983ac8650c5b813cb217a8 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 15:41:56 +0900 Subject: [PATCH 31/38] =?UTF-8?q?refactor:=20=EC=97=AD=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EC=A0=84=EB=9E=B5=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/core/Direction.java | 12 ++++++------ ...LeftStrategy.java => StationAddLeftStrategy.java} | 2 +- ...ghtStrategy.java => StationAddRightStrategy.java} | 2 +- ...dStationStrategy.java => StationAddStrategy.java} | 2 +- ...tegyTest.java => StationAddLeftStrategyTest.java} | 8 ++++---- ...egyTest.java => StationAddRightStrategyTest.java} | 8 ++++---- ...StrategyTest.java => StationAddStrategyTest.java} | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) rename src/main/java/subway/domain/core/{AddStationToLeftStrategy.java => StationAddLeftStrategy.java} (91%) rename src/main/java/subway/domain/core/{AddStationToRightStrategy.java => StationAddRightStrategy.java} (91%) rename src/main/java/subway/domain/core/{AddStationStrategy.java => StationAddStrategy.java} (93%) rename src/test/java/subway/domain/core/{AddStationToLeftStrategyTest.java => StationAddLeftStrategyTest.java} (79%) rename src/test/java/subway/domain/core/{AddStationToRightStrategyTest.java => StationAddRightStrategyTest.java} (79%) rename src/test/java/subway/domain/core/{AddStationStrategyTest.java => StationAddStrategyTest.java} (90%) diff --git a/src/main/java/subway/domain/core/Direction.java b/src/main/java/subway/domain/core/Direction.java index 3465ae38f..db4a18483 100644 --- a/src/main/java/subway/domain/core/Direction.java +++ b/src/main/java/subway/domain/core/Direction.java @@ -3,14 +3,14 @@ import java.util.List; public enum Direction { - LEFT(new AddStationToLeftStrategy()), - RIGHT(new AddStationToRightStrategy()), + LEFT(new StationAddLeftStrategy()), + RIGHT(new StationAddRightStrategy()), ; - private final AddStationStrategy addStationStrategy; + private final StationAddStrategy stationAddStrategy; - Direction(final AddStationStrategy addStationStrategy) { - this.addStationStrategy = addStationStrategy; + Direction(final StationAddStrategy stationAddStrategy) { + this.stationAddStrategy = stationAddStrategy; } public Direction flip() { @@ -26,6 +26,6 @@ public void addStation( final Station additional, final Distance distance ) { - addStationStrategy.add(sections, base, additional, distance); + stationAddStrategy.add(sections, base, additional, distance); } } diff --git a/src/main/java/subway/domain/core/AddStationToLeftStrategy.java b/src/main/java/subway/domain/core/StationAddLeftStrategy.java similarity index 91% rename from src/main/java/subway/domain/core/AddStationToLeftStrategy.java rename to src/main/java/subway/domain/core/StationAddLeftStrategy.java index af1c266d6..a30d4fff6 100644 --- a/src/main/java/subway/domain/core/AddStationToLeftStrategy.java +++ b/src/main/java/subway/domain/core/StationAddLeftStrategy.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Optional; -public class AddStationToLeftStrategy implements AddStationStrategy { +public class StationAddLeftStrategy implements StationAddStrategy { @Override public void add( final List
sections, diff --git a/src/main/java/subway/domain/core/AddStationToRightStrategy.java b/src/main/java/subway/domain/core/StationAddRightStrategy.java similarity index 91% rename from src/main/java/subway/domain/core/AddStationToRightStrategy.java rename to src/main/java/subway/domain/core/StationAddRightStrategy.java index ee24df0f7..7c160549a 100644 --- a/src/main/java/subway/domain/core/AddStationToRightStrategy.java +++ b/src/main/java/subway/domain/core/StationAddRightStrategy.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Optional; -public class AddStationToRightStrategy implements AddStationStrategy { +public class StationAddRightStrategy implements StationAddStrategy { @Override public void add( final List
sections, diff --git a/src/main/java/subway/domain/core/AddStationStrategy.java b/src/main/java/subway/domain/core/StationAddStrategy.java similarity index 93% rename from src/main/java/subway/domain/core/AddStationStrategy.java rename to src/main/java/subway/domain/core/StationAddStrategy.java index 2c9359814..d281eb058 100644 --- a/src/main/java/subway/domain/core/AddStationStrategy.java +++ b/src/main/java/subway/domain/core/StationAddStrategy.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Optional; -public interface AddStationStrategy { +public interface StationAddStrategy { void add(final List
sections, final Station base, final Station additional, final Distance distance); diff --git a/src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java b/src/test/java/subway/domain/core/StationAddLeftStrategyTest.java similarity index 79% rename from src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java rename to src/test/java/subway/domain/core/StationAddLeftStrategyTest.java index f53a461f2..386224a35 100644 --- a/src/test/java/subway/domain/core/AddStationToLeftStrategyTest.java +++ b/src/test/java/subway/domain/core/StationAddLeftStrategyTest.java @@ -10,9 +10,9 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class AddStationToLeftStrategyTest { +class StationAddLeftStrategyTest { - final AddStationStrategy addStationToLeftStrategy = new AddStationToLeftStrategy(); + final StationAddStrategy stationAddStrategy = new StationAddLeftStrategy(); @Test void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์™ผ์ชฝ_๋ฐฉํ–ฅ์œผ๋กœ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { @@ -23,7 +23,7 @@ class AddStationToLeftStrategyTest { )); // when - addStationToLeftStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); + stationAddStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); // then assertThat(sections).contains( @@ -42,7 +42,7 @@ class AddStationToLeftStrategyTest { )); // when - addStationToLeftStrategy.add(sections, new Station("A"), new Station("D"), new Distance(2)); + stationAddStrategy.add(sections, new Station("A"), new Station("D"), new Distance(2)); // then assertThat(sections).contains( diff --git a/src/test/java/subway/domain/core/AddStationToRightStrategyTest.java b/src/test/java/subway/domain/core/StationAddRightStrategyTest.java similarity index 79% rename from src/test/java/subway/domain/core/AddStationToRightStrategyTest.java rename to src/test/java/subway/domain/core/StationAddRightStrategyTest.java index a8b690039..18f48a3de 100644 --- a/src/test/java/subway/domain/core/AddStationToRightStrategyTest.java +++ b/src/test/java/subway/domain/core/StationAddRightStrategyTest.java @@ -10,9 +10,9 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class AddStationToRightStrategyTest { +class StationAddRightStrategyTest { - final AddStationStrategy addStationToLeftStrategy = new AddStationToRightStrategy(); + final StationAddStrategy stationAddStrategy = new StationAddRightStrategy(); @Test void ๊ตฌ๊ฐ„_์‚ฌ์ด์—_์˜ค๋ฅธ์ชฝ_๋ฐฉํ–ฅ์œผ๋กœ_์—ญ์„_์ถ”๊ฐ€ํ•œ๋‹ค() { @@ -23,7 +23,7 @@ class AddStationToRightStrategyTest { )); // when - addStationToLeftStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); + stationAddStrategy.add(sections, new Station("B"), new Station("D"), new Distance(2)); // then assertThat(sections).contains( @@ -42,7 +42,7 @@ class AddStationToRightStrategyTest { )); // when - addStationToLeftStrategy.add(sections, new Station("C"), new Station("D"), new Distance(2)); + stationAddStrategy.add(sections, new Station("C"), new Station("D"), new Distance(2)); // then assertThat(sections).contains( diff --git a/src/test/java/subway/domain/core/AddStationStrategyTest.java b/src/test/java/subway/domain/core/StationAddStrategyTest.java similarity index 90% rename from src/test/java/subway/domain/core/AddStationStrategyTest.java rename to src/test/java/subway/domain/core/StationAddStrategyTest.java index 296efa018..b7ef6fe0e 100644 --- a/src/test/java/subway/domain/core/AddStationStrategyTest.java +++ b/src/test/java/subway/domain/core/StationAddStrategyTest.java @@ -9,9 +9,9 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class AddStationStrategyTest { +class StationAddStrategyTest { - private AddStationStrategy sut = (sections, base, additional, distance) -> { + private StationAddStrategy sut = (sections, base, additional, distance) -> { }; @Test From ed3018894f06a4f752206cc9b3587cfd7b169670 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 16:32:23 +0900 Subject: [PATCH 32/38] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=EB=A5=BC=20?= =?UTF-8?q?=ED=91=9C=ED=98=84=ED=95=98=EB=8A=94=20Path=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/path/Path.java | 24 ++++++++++++++ .../java/subway/domain/path/PathTest.java | 31 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/main/java/subway/domain/path/Path.java create mode 100644 src/test/java/subway/domain/path/PathTest.java diff --git a/src/main/java/subway/domain/path/Path.java b/src/main/java/subway/domain/path/Path.java new file mode 100644 index 000000000..ca9c84381 --- /dev/null +++ b/src/main/java/subway/domain/path/Path.java @@ -0,0 +1,24 @@ +package subway.domain.path; + +import java.util.List; +import subway.domain.core.Section; + +public class Path { + + private final List sectionEdges; + + public Path(final List sectionEdges) { + this.sectionEdges = sectionEdges; + } + + public int calculateTotalDistance() { + return sectionEdges.stream() + .map(SectionEdge::toSection) + .mapToInt(Section::getDistanceValue) + .sum(); + } + + public List sectionEdges() { + return sectionEdges; + } +} diff --git a/src/test/java/subway/domain/path/PathTest.java b/src/test/java/subway/domain/path/PathTest.java new file mode 100644 index 000000000..1f8159b71 --- /dev/null +++ b/src/test/java/subway/domain/path/PathTest.java @@ -0,0 +1,31 @@ +package subway.domain.path; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import subway.domain.core.Section; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class PathTest { + + @Test + void ๊ฒฝ๋กœ์˜_์ด_๊ฑฐ๋ฆฌ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { + // given + final Path path = new Path(List.of( + new SectionEdge(new Section("A", "B", 2), 300, 1), + new SectionEdge(new Section("B", "C", 5), 300, 1), + new SectionEdge(new Section("C", "T", 7), 500, 2), + new SectionEdge(new Section("T", "D", 4), 300, 1) + )); + + // when + final int result = path.calculateTotalDistance(); + + // then + assertThat(result).isEqualTo(18); + } +} From ec7fcf886022a4741bb0431fa23b538034cdb4d1 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 16:39:05 +0900 Subject: [PATCH 33/38] =?UTF-8?q?refactor:=20PathFindResult=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=ED=95=98=EA=B3=A0=20Path=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/fare/AgeDiscountFarePolicy.java | 4 +-- .../subway/domain/fare/BaseFarePolicy.java | 11 ++++---- .../domain/fare/DistanceFarePolicy.java | 6 ++-- .../java/subway/domain/fare/FarePolicy.java | 4 +-- .../subway/domain/fare/SubwayFarePolicy.java | 6 ++-- src/main/java/subway/domain/path/Path.java | 2 +- .../subway/domain/path/PathFindResult.java | 23 --------------- .../java/subway/domain/path/PathFinder.java | 5 ++-- src/main/java/subway/service/PathService.java | 8 +++--- .../fare/AgeDiscountFarePolicyTest.java | 7 ++--- .../domain/fare/BaseFarePolicyTest.java | 11 ++++---- .../domain/fare/DistanceFarePolicyTest.java | 28 +++++++++++++------ .../domain/fare/SubwayFarePolicyTest.java | 7 ++--- .../subway/domain/path/PathFinderTest.java | 6 ++-- 14 files changed, 55 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/subway/domain/path/PathFindResult.java diff --git a/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java index ef642caed..63ac690da 100644 --- a/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java +++ b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java @@ -1,11 +1,11 @@ package subway.domain.fare; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; public class AgeDiscountFarePolicy implements FarePolicy { @Override - public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + public int calculate(final Path path, final Passenger passenger, final int fare) { return passenger.calculateFare(fare); } } diff --git a/src/main/java/subway/domain/fare/BaseFarePolicy.java b/src/main/java/subway/domain/fare/BaseFarePolicy.java index 028d03952..fddc79941 100644 --- a/src/main/java/subway/domain/fare/BaseFarePolicy.java +++ b/src/main/java/subway/domain/fare/BaseFarePolicy.java @@ -1,8 +1,7 @@ package subway.domain.fare; import java.util.Comparator; -import java.util.List; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; import subway.domain.path.SectionEdge; public class BaseFarePolicy implements FarePolicy { @@ -10,12 +9,12 @@ public class BaseFarePolicy implements FarePolicy { private static final int BASE_AMOUNT = 1250; @Override - public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { - return fare + BASE_AMOUNT + calculateMaxSurcharge(result.getPath()); + public int calculate(final Path path, final Passenger passenger, final int fare) { + return fare + BASE_AMOUNT + calculateMaxSurcharge(path); } - private int calculateMaxSurcharge(final List path) { - return path.stream() + private int calculateMaxSurcharge(final Path path) { + return path.getSectionEdges().stream() .map(SectionEdge::getSurcharge) .max(Comparator.naturalOrder()) .orElse(0); diff --git a/src/main/java/subway/domain/fare/DistanceFarePolicy.java b/src/main/java/subway/domain/fare/DistanceFarePolicy.java index 9aafdfab7..30bd78aca 100644 --- a/src/main/java/subway/domain/fare/DistanceFarePolicy.java +++ b/src/main/java/subway/domain/fare/DistanceFarePolicy.java @@ -3,7 +3,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; public class DistanceFarePolicy implements FarePolicy { @@ -14,8 +14,8 @@ public class DistanceFarePolicy implements FarePolicy { private static final int MORE_THAN_EXTRA_FARE_UNIT = 8; @Override - public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { - final int distance = result.getDistanceValue(); + public int calculate(final Path path, final Passenger passenger, final int fare) { + final int distance = path.calculateTotalDistance(); final int extraDistance = min( EXTRA_FARE_SEGMENT - NO_EXTRA_FARE_DISTANCE, diff --git a/src/main/java/subway/domain/fare/FarePolicy.java b/src/main/java/subway/domain/fare/FarePolicy.java index 9fb6c3c30..a39e095bc 100644 --- a/src/main/java/subway/domain/fare/FarePolicy.java +++ b/src/main/java/subway/domain/fare/FarePolicy.java @@ -1,8 +1,8 @@ package subway.domain.fare; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; public interface FarePolicy { - int calculate(final PathFindResult result, final Passenger passenger, final int fare); + int calculate(final Path path, final Passenger passenger, final int fare); } diff --git a/src/main/java/subway/domain/fare/SubwayFarePolicy.java b/src/main/java/subway/domain/fare/SubwayFarePolicy.java index aa332bdc8..abeec097a 100644 --- a/src/main/java/subway/domain/fare/SubwayFarePolicy.java +++ b/src/main/java/subway/domain/fare/SubwayFarePolicy.java @@ -1,7 +1,7 @@ package subway.domain.fare; import java.util.List; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; public class SubwayFarePolicy implements FarePolicy { @@ -12,10 +12,10 @@ public SubwayFarePolicy(final List farePolicies) { } @Override - public int calculate(final PathFindResult result, final Passenger passenger, final int fare) { + public int calculate(final Path path, final Passenger passenger, final int fare) { int calculatedFare = fare; for (FarePolicy farePolicy : farePolicies) { - calculatedFare = farePolicy.calculate(result, passenger, calculatedFare); + calculatedFare = farePolicy.calculate(path, passenger, calculatedFare); } return calculatedFare; } diff --git a/src/main/java/subway/domain/path/Path.java b/src/main/java/subway/domain/path/Path.java index ca9c84381..62558d0a6 100644 --- a/src/main/java/subway/domain/path/Path.java +++ b/src/main/java/subway/domain/path/Path.java @@ -18,7 +18,7 @@ public int calculateTotalDistance() { .sum(); } - public List sectionEdges() { + public List getSectionEdges() { return sectionEdges; } } diff --git a/src/main/java/subway/domain/path/PathFindResult.java b/src/main/java/subway/domain/path/PathFindResult.java deleted file mode 100644 index 10f4875a3..000000000 --- a/src/main/java/subway/domain/path/PathFindResult.java +++ /dev/null @@ -1,23 +0,0 @@ -package subway.domain.path; - -import java.util.List; -import subway.domain.core.Distance; - -public class PathFindResult { - - private final Distance distance; - private final List path; - - public PathFindResult(final Distance distance, final List path) { - this.distance = distance; - this.path = path; - } - - public int getDistanceValue() { - return distance.getValue(); - } - - public List getPath() { - return path; - } -} diff --git a/src/main/java/subway/domain/path/PathFinder.java b/src/main/java/subway/domain/path/PathFinder.java index 23af833a8..4d1af6cca 100644 --- a/src/main/java/subway/domain/path/PathFinder.java +++ b/src/main/java/subway/domain/path/PathFinder.java @@ -3,7 +3,6 @@ import org.jgrapht.GraphPath; import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.WeightedMultigraph; -import subway.domain.core.Distance; import subway.domain.core.Line; import subway.domain.core.Section; import subway.domain.core.Station; @@ -17,10 +16,10 @@ public PathFinder(final Subway subway) { this.subway = subway; } - public PathFindResult find(final String start, final String end) { + public Path find(final String start, final String end) { final DijkstraShortestPath shortestPath = initializeShortestPath(); final GraphPath path = shortestPath.getPath(start, end); - return new PathFindResult(new Distance(path.getWeight()), path.getEdgeList()); + return new Path(path.getEdgeList()); } private DijkstraShortestPath initializeShortestPath() { diff --git a/src/main/java/subway/service/PathService.java b/src/main/java/subway/service/PathService.java index bd8179966..27e10982b 100644 --- a/src/main/java/subway/service/PathService.java +++ b/src/main/java/subway/service/PathService.java @@ -9,7 +9,7 @@ import subway.domain.core.Subway; import subway.domain.fare.FarePolicy; import subway.domain.fare.Passenger; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; import subway.domain.path.PathFinder; import subway.domain.path.SectionEdge; import subway.dto.LineDto; @@ -34,9 +34,9 @@ public PathService(final LineRepository lineRepository, final FarePolicy farePol public ShortestPathResponse shortestPath(final ShortestPathRequest request) { final Subway subway = new Subway(lineRepository.findAll()); final PathFinder pathFinder = new PathFinder(subway); - final PathFindResult result = pathFinder.find(request.getStart(), request.getEnd()); - final int fare = farePolicy.calculate(result, new Passenger(request.getAge()), 0); - return new ShortestPathResponse(toLineDtos(result.getPath()), result.getDistanceValue(), fare); + final Path path = pathFinder.find(request.getStart(), request.getEnd()); + final int fare = farePolicy.calculate(path, new Passenger(request.getAge()), 0); + return new ShortestPathResponse(toLineDtos(path.getSectionEdges()), path.calculateTotalDistance(), fare); } private List toLineDtos(final List path) { diff --git a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java index caa14d5a9..91241840c 100644 --- a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java @@ -6,8 +6,7 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.core.Distance; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @@ -18,12 +17,12 @@ class AgeDiscountFarePolicyTest { @Test void ๋‚˜์ด์—_๋”ฐ๋ผ_๊ธˆ์•ก์„_๊ณ„์‚ฐํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(5), Collections.emptyList()); + final Path path = new Path(Collections.emptyList()); final Passenger passenger = new Passenger(17); final int fare = 1250; // when - final int result = farePolicy.calculate(pathFindResult, passenger, fare); + final int result = farePolicy.calculate(path, passenger, fare); // then assertThat(result).isEqualTo(720); diff --git a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java index f1b1b7928..3e1ea8309 100644 --- a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java @@ -7,9 +7,8 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.core.Distance; import subway.domain.core.Section; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; import subway.domain.path.SectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -21,11 +20,11 @@ class BaseFarePolicyTest { @Test void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›์„_๋”ํ•œ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); + final Path path = new Path(Collections.emptyList()); final Passenger passenger = new Passenger(20); // when - final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); + final int result = baseFarePolicy.calculate(path, passenger, 0); // then assertThat(result).isEqualTo(1250); @@ -34,7 +33,7 @@ class BaseFarePolicyTest { @Test void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›๊ณผ_๋…ธ์„ ์šด์ž„_์ค‘_๊ฐ€์žฅ๋†’์€_๊ฐ’์„_๋”ํ•˜์—ฌ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(9), List.of( + final Path path = new Path(List.of( new SectionEdge(new Section("A", "B", 5), 100, 1), new SectionEdge(new Section("B", "C", 10), 100, 1), new SectionEdge(new Section("C", "T", 10), 300, 2), @@ -43,7 +42,7 @@ class BaseFarePolicyTest { final Passenger passenger = new Passenger(20); // when - final int result = baseFarePolicy.calculate(pathFindResult, passenger, 0); + final int result = baseFarePolicy.calculate(path, passenger, 0); // then assertThat(result).isEqualTo(1550); diff --git a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java index 1e7b191b0..5efc15894 100644 --- a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java @@ -2,12 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.core.Distance; -import subway.domain.path.PathFindResult; +import subway.domain.core.Section; +import subway.domain.path.Path; +import subway.domain.path.SectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @@ -18,11 +19,14 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_๋ฐœ์ƒํ•˜์ง€_์•Š๋Š”๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(9), Collections.emptyList()); + final Path path = new Path(List.of( + new SectionEdge(new Section("A", "B", 4), 100, 1), + new SectionEdge(new Section("B", "C", 5), 100, 1) + )); final Passenger passenger = new Passenger(20); // when - final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + final int result = farePolicy.calculate(path, passenger, 1250); // then assertThat(result).usingRecursiveComparison().isEqualTo(1250); @@ -31,11 +35,14 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๊ณ _50ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_5KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(27), Collections.emptyList()); + final Path path = new Path(List.of( + new SectionEdge(new Section("A", "B", 20), 100, 1), + new SectionEdge(new Section("B", "C", 7), 100, 1) + )); final Passenger passenger = new Passenger(20); // when - final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + final int result = farePolicy.calculate(path, passenger, 1250); // then assertThat(result).isEqualTo(1650); @@ -44,11 +51,14 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_50ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_8KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(61), Collections.emptyList()); + final Path path = new Path(List.of( + new SectionEdge(new Section("A", "B", 60), 100, 1), + new SectionEdge(new Section("B", "C", 1), 100, 1) + )); final Passenger passenger = new Passenger(20); // when - final int result = farePolicy.calculate(pathFindResult, passenger, 1250); + final int result = farePolicy.calculate(path, passenger, 1250); // then assertThat(result).isEqualTo(2250); diff --git a/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java index 5f418aa9c..d56abad79 100644 --- a/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java @@ -6,9 +6,8 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.core.Distance; import subway.domain.core.Section; -import subway.domain.path.PathFindResult; +import subway.domain.path.Path; import subway.domain.path.SectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -24,7 +23,7 @@ class SubwayFarePolicyTest { @Test void ์ตœ์ข…_์šด์ž„์„_๊ณ„์‚ฐํ•œ๋‹ค() { // given - final PathFindResult pathFindResult = new PathFindResult(new Distance(35), List.of( + final Path path = new Path(List.of( new SectionEdge(new Section("A", "B", 5), 300, 1), new SectionEdge(new Section("B", "C", 10), 300, 1), new SectionEdge(new Section("C", "T", 10), 500, 2), @@ -33,7 +32,7 @@ class SubwayFarePolicyTest { final Passenger passenger = new Passenger(17); // when - final int result = farePolicy.calculate(pathFindResult, passenger, 0); + final int result = farePolicy.calculate(path, passenger, 0); // then assertThat(result).isEqualTo(1520); diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/domain/path/PathFinderTest.java index f8edcf4cc..239b2e4c1 100644 --- a/src/test/java/subway/domain/path/PathFinderTest.java +++ b/src/test/java/subway/domain/path/PathFinderTest.java @@ -31,12 +31,12 @@ class PathFinderTest { final PathFinder pathFinder = new PathFinder(subway); // when - final PathFindResult pathFindResult = pathFinder.find("A", "Y"); + final Path path = pathFinder.find("A", "Y"); // then assertAll( - () -> assertThat(pathFindResult.getDistanceValue()).isEqualTo(7), - () -> assertThat(pathFindResult.getPath()) + () -> assertThat(path.calculateTotalDistance()).isEqualTo(7), + () -> assertThat(path.getSectionEdges()) .extracting(SectionEdge::toSection) .usingRecursiveComparison() .ignoringExpectedNullFields() From ba84f581edd9806306a3cd401ba80a406233a5c6 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 16:41:12 +0900 Subject: [PATCH 34/38] =?UTF-8?q?remove:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20Distance=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/core/Distance.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/subway/domain/core/Distance.java b/src/main/java/subway/domain/core/Distance.java index cd1a1852b..ffc768188 100644 --- a/src/main/java/subway/domain/core/Distance.java +++ b/src/main/java/subway/domain/core/Distance.java @@ -8,11 +8,7 @@ public class Distance { private static final int MINIMUM_DISTANCE_VALUE = 1; private final int value; - - public Distance(final Double value) { - this(value.intValue()); - } - + public Distance(final int value) { validate(value); this.value = value; From 32bc91f3a93c365303c93c8f1abad8a1842bcb59 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 16:50:38 +0900 Subject: [PATCH 35/38] =?UTF-8?q?refactor:=20Passenger=EA=B0=80=20?= =?UTF-8?q?=EB=82=98=EC=9D=B4=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A7=80=EA=B3=A0=20=EC=9E=88=EB=8F=84=EB=A1=9D,=20AgeDiscount?= =?UTF-8?q?FarePolicy=EA=B0=80=20=EA=B3=84=EC=82=B0=EC=9D=98=20=EC=B1=85?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/fare/AgeDiscountFarePolicy.java | 4 +- .../java/subway/domain/fare/AgeGroup.java | 9 ++-- .../java/subway/domain/fare/Passenger.java | 8 +-- .../fare/AgeDiscountFarePolicyTest.java | 44 +++++++++++++++- .../java/subway/domain/fare/AgeGroupTest.java | 52 ------------------- .../subway/domain/fare/PassengerTest.java | 7 ++- 6 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java index 63ac690da..013e47fff 100644 --- a/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java +++ b/src/main/java/subway/domain/fare/AgeDiscountFarePolicy.java @@ -6,6 +6,8 @@ public class AgeDiscountFarePolicy implements FarePolicy { @Override public int calculate(final Path path, final Passenger passenger, final int fare) { - return passenger.calculateFare(fare); + final AgeGroup ageGroup = passenger.calulateAgeGroup(); + final int discountedFare = fare - ageGroup.getDiscountFare(); + return (int) (discountedFare - discountedFare * ageGroup.getDiscountRatio()); } } diff --git a/src/main/java/subway/domain/fare/AgeGroup.java b/src/main/java/subway/domain/fare/AgeGroup.java index f863c2e45..e14e0bb16 100644 --- a/src/main/java/subway/domain/fare/AgeGroup.java +++ b/src/main/java/subway/domain/fare/AgeGroup.java @@ -29,8 +29,11 @@ public static AgeGroup from(final int age) { .orElseThrow(InvalidAgeException::new); } - public int calculateFare(final int fare) { - final int result = fare - discountFare; - return (int) (result - result * discountRatio); + public int getDiscountFare() { + return discountFare; + } + + public double getDiscountRatio() { + return discountRatio; } } diff --git a/src/main/java/subway/domain/fare/Passenger.java b/src/main/java/subway/domain/fare/Passenger.java index 60c668d3f..732669e18 100644 --- a/src/main/java/subway/domain/fare/Passenger.java +++ b/src/main/java/subway/domain/fare/Passenger.java @@ -2,13 +2,13 @@ public class Passenger { - private AgeGroup ageGroup; + private int age; public Passenger(final int age) { - this.ageGroup = AgeGroup.from(age); + this.age = age; } - public int calculateFare(final int fare) { - return ageGroup.calculateFare(fare); + public AgeGroup calulateAgeGroup() { + return AgeGroup.from(age); } } diff --git a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java index 91241840c..e78e35dae 100644 --- a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java @@ -15,10 +15,24 @@ class AgeDiscountFarePolicyTest { private FarePolicy farePolicy = new AgeDiscountFarePolicy(); @Test - void ๋‚˜์ด์—_๋”ฐ๋ผ_๊ธˆ์•ก์„_๊ณ„์‚ฐํ•œ๋‹ค() { + void ์„ฑ์ธ์˜_๊ฒฝ์šฐ_ํ• ์ธ์ด_์ ์šฉ๋˜์ง€_์•Š๋Š”๋‹ค() { // given final Path path = new Path(Collections.emptyList()); - final Passenger passenger = new Passenger(17); + final Passenger passenger = new Passenger(19); + final int fare = 1250; + + // when + final int result = farePolicy.calculate(path, passenger, fare); + + // then + assertThat(result).isEqualTo(1250); + } + + @Test + void ์ฒญ์†Œ๋…„์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_20ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { + // given + final Path path = new Path(Collections.emptyList()); + final Passenger passenger = new Passenger(18); final int fare = 1250; // when @@ -27,4 +41,30 @@ class AgeDiscountFarePolicyTest { // then assertThat(result).isEqualTo(720); } + + @Test + void ์–ด๋ฆฐ์ด์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_50ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { + final Path path = new Path(Collections.emptyList()); + final Passenger passenger = new Passenger(6); + final int fare = 1250; + + // when + final int result = farePolicy.calculate(path, passenger, fare); + + // then + assertThat(result).isEqualTo(450); + } + + @Test + void ์œ ์•„์˜_๊ฒฝ์šฐ_๋ฌด๋ฃŒ๋‹ค() { + final Path path = new Path(Collections.emptyList()); + final Passenger passenger = new Passenger(5); + final int fare = 1250; + + // when + final int result = farePolicy.calculate(path, passenger, fare); + + // then + assertThat(result).isZero(); + } } diff --git a/src/test/java/subway/domain/fare/AgeGroupTest.java b/src/test/java/subway/domain/fare/AgeGroupTest.java index de24c4447..84e06d113 100644 --- a/src/test/java/subway/domain/fare/AgeGroupTest.java +++ b/src/test/java/subway/domain/fare/AgeGroupTest.java @@ -2,10 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static subway.domain.fare.AgeGroup.ADULT; -import static subway.domain.fare.AgeGroup.BABY; -import static subway.domain.fare.AgeGroup.CHILD; -import static subway.domain.fare.AgeGroup.YOUTH; import static subway.domain.fare.AgeGroup.from; import org.junit.jupiter.api.DisplayNameGeneration; @@ -39,52 +35,4 @@ class AgeGroupTest { void ์˜ฌ๋ฐ”๋ฅธ_๋‚˜์ด์ธ_๊ฒฝ์šฐ_ํ•ด๋‹น_๋‚˜์ด์—_๋งž๋Š”_๊ทธ๋ฃน์„_๋ฐ˜ํ™˜ํ•œ๋‹ค(final int age, final AgeGroup group) { assertThat(from(age)).isEqualTo(group); } - - @Test - void ์„ฑ์ธ์˜_๊ฒฝ์šฐ_ํ• ์ธ์ด_์ ์šฉ๋˜์ง€_์•Š๋Š”๋‹ค() { - // given - final int fare = 1250; - - // when - final int result = ADULT.calculateFare(fare); - - // then - assertThat(result).isEqualTo(1250); - } - - @Test - void ์ฒญ์†Œ๋…„์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_20ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { - // given - final int fare = 1250; - - // when - final int result = YOUTH.calculateFare(fare); - - // then - assertThat(result).isEqualTo(720); - } - - @Test - void ์–ด๋ฆฐ์ด์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_50ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { - // given - final int fare = 1250; - - // when - final int result = CHILD.calculateFare(fare); - - // then - assertThat(result).isEqualTo(450); - } - - @Test - void ์œ ์•„์˜_๊ฒฝ์šฐ_๋ฌด๋ฃŒ๋‹ค() { - // given - final int fare = 1250; - - // when - final int result = BABY.calculateFare(fare); - - // then - assertThat(result).isZero(); - } } diff --git a/src/test/java/subway/domain/fare/PassengerTest.java b/src/test/java/subway/domain/fare/PassengerTest.java index f5ced453e..ca6a01516 100644 --- a/src/test/java/subway/domain/fare/PassengerTest.java +++ b/src/test/java/subway/domain/fare/PassengerTest.java @@ -11,15 +11,14 @@ class PassengerTest { @Test - void ๋‚˜์ด์—_๋”ฐ๋ผ_๊ธˆ์•ก์„_๊ณ„์‚ฐํ•œ๋‹ค() { + void ๋‚˜์ด์—_ํ•ด๋‹นํ•˜๋Š”_AgeGroup์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given final Passenger passenger = new Passenger(17); - final int fare = 1250; // when - final int result = passenger.calculateFare(fare); + final AgeGroup result = passenger.calulateAgeGroup(); // then - assertThat(result).isEqualTo(720); + assertThat(result).isEqualTo(AgeGroup.YOUTH); } } From d5bc4a73592485332e5232c262c8c8bedfb39483 Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 17:10:45 +0900 Subject: [PATCH 36/38] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EC=97=90=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4?= =?UTF-8?q?=EB=A5=BC=20=EB=91=90=EA=B3=A0=20Jgrapht=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/path/Path.java | 20 +------ .../java/subway/domain/path/PathFinder.java | 49 +---------------- .../java/subway/domain/path/SectionEdge.java | 25 ++------- src/main/java/subway/jgraph/JgraphtPath.java | 28 ++++++++++ .../java/subway/jgraph/JgraphtPathFinder.java | 55 +++++++++++++++++++ .../subway/jgraph/JgraphtSectionEdge.java | 33 +++++++++++ src/main/java/subway/service/PathService.java | 3 +- .../fare/AgeDiscountFarePolicyTest.java | 10 ++-- .../domain/fare/BaseFarePolicyTest.java | 34 +++++++++--- .../domain/fare/DistanceFarePolicyTest.java | 23 +++----- .../domain/fare/SubwayFarePolicyTest.java | 32 +++++++++-- .../JgraphtPathFinderTest.java} | 10 +++- .../JgraphtPathTest.java} | 17 +++--- .../JgraphtSectionEdgeTest.java} | 8 ++- 14 files changed, 216 insertions(+), 131 deletions(-) create mode 100644 src/main/java/subway/jgraph/JgraphtPath.java create mode 100644 src/main/java/subway/jgraph/JgraphtPathFinder.java create mode 100644 src/main/java/subway/jgraph/JgraphtSectionEdge.java rename src/test/java/subway/{domain/path/PathFinderTest.java => jgrapht/JgraphtPathFinderTest.java} (85%) rename src/test/java/subway/{domain/path/PathTest.java => jgrapht/JgraphtPathTest.java} (54%) rename src/test/java/subway/{domain/path/SectionEdgeTest.java => jgrapht/JgraphtSectionEdgeTest.java} (71%) diff --git a/src/main/java/subway/domain/path/Path.java b/src/main/java/subway/domain/path/Path.java index 62558d0a6..a12e4e55f 100644 --- a/src/main/java/subway/domain/path/Path.java +++ b/src/main/java/subway/domain/path/Path.java @@ -1,24 +1,10 @@ package subway.domain.path; import java.util.List; -import subway.domain.core.Section; -public class Path { +public interface Path { - private final List sectionEdges; + int calculateTotalDistance(); - public Path(final List sectionEdges) { - this.sectionEdges = sectionEdges; - } - - public int calculateTotalDistance() { - return sectionEdges.stream() - .map(SectionEdge::toSection) - .mapToInt(Section::getDistanceValue) - .sum(); - } - - public List getSectionEdges() { - return sectionEdges; - } + List getSectionEdges(); } diff --git a/src/main/java/subway/domain/path/PathFinder.java b/src/main/java/subway/domain/path/PathFinder.java index 4d1af6cca..69e293a3c 100644 --- a/src/main/java/subway/domain/path/PathFinder.java +++ b/src/main/java/subway/domain/path/PathFinder.java @@ -1,51 +1,6 @@ package subway.domain.path; -import org.jgrapht.GraphPath; -import org.jgrapht.alg.shortestpath.DijkstraShortestPath; -import org.jgrapht.graph.WeightedMultigraph; -import subway.domain.core.Line; -import subway.domain.core.Section; -import subway.domain.core.Station; -import subway.domain.core.Subway; +public interface PathFinder { -public class PathFinder { - - private final Subway subway; - - public PathFinder(final Subway subway) { - this.subway = subway; - } - - public Path find(final String start, final String end) { - final DijkstraShortestPath shortestPath = initializeShortestPath(); - final GraphPath path = shortestPath.getPath(start, end); - return new Path(path.getEdgeList()); - } - - private DijkstraShortestPath initializeShortestPath() { - final WeightedMultigraph graph = new WeightedMultigraph<>(SectionEdge.class); - addVertex(graph); - addEdge(graph); - return new DijkstraShortestPath<>(graph); - } - - private void addVertex(final WeightedMultigraph graph) { - subway.getStations().stream() - .map(Station::getName) - .forEach(graph::addVertex); - } - - private void addEdge(final WeightedMultigraph graph) { - for (final Line line : subway.getLines()) { - addEdgeByLine(graph, line); - } - } - - private void addEdgeByLine(final WeightedMultigraph graph, final Line line) { - for (final Section section : line.getSections()) { - final SectionEdge sectionEdge = new SectionEdge(section, line.getSurcharge(), line.getId()); - graph.addEdge(section.getStartName(), section.getEndName(), sectionEdge); - graph.setEdgeWeight(sectionEdge, section.getDistanceValue()); - } - } + Path find(final String start, final String end); } diff --git a/src/main/java/subway/domain/path/SectionEdge.java b/src/main/java/subway/domain/path/SectionEdge.java index dd51dbcc3..b0e3cd610 100644 --- a/src/main/java/subway/domain/path/SectionEdge.java +++ b/src/main/java/subway/domain/path/SectionEdge.java @@ -1,29 +1,12 @@ package subway.domain.path; -import org.jgrapht.graph.DefaultWeightedEdge; import subway.domain.core.Section; -public class SectionEdge extends DefaultWeightedEdge { +public interface SectionEdge { - private final Section section; - private final int surcharge; - private final long lineId; + Section toSection(); - public SectionEdge(final Section section, final int surcharge, final long lineId) { - this.section = section; - this.surcharge = surcharge; - this.lineId = lineId; - } + int getSurcharge(); - public Section toSection() { - return section; - } - - public int getSurcharge() { - return surcharge; - } - - public long getLineId() { - return lineId; - } + long getLineId(); } diff --git a/src/main/java/subway/jgraph/JgraphtPath.java b/src/main/java/subway/jgraph/JgraphtPath.java new file mode 100644 index 000000000..6ca4f40c8 --- /dev/null +++ b/src/main/java/subway/jgraph/JgraphtPath.java @@ -0,0 +1,28 @@ +package subway.jgraph; + +import java.util.List; +import subway.domain.core.Section; +import subway.domain.path.Path; +import subway.domain.path.SectionEdge; + +public class JgraphtPath implements Path { + + private final List sectionEdges; + + public JgraphtPath(final List sectionEdges) { + this.sectionEdges = sectionEdges; + } + + @Override + public int calculateTotalDistance() { + return sectionEdges.stream() + .map(SectionEdge::toSection) + .mapToInt(Section::getDistanceValue) + .sum(); + } + + @Override + public List getSectionEdges() { + return sectionEdges; + } +} diff --git a/src/main/java/subway/jgraph/JgraphtPathFinder.java b/src/main/java/subway/jgraph/JgraphtPathFinder.java new file mode 100644 index 000000000..15776c1f0 --- /dev/null +++ b/src/main/java/subway/jgraph/JgraphtPathFinder.java @@ -0,0 +1,55 @@ +package subway.jgraph; + +import org.jgrapht.GraphPath; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import org.jgrapht.graph.WeightedMultigraph; +import subway.domain.core.Line; +import subway.domain.core.Section; +import subway.domain.core.Station; +import subway.domain.core.Subway; +import subway.domain.path.Path; +import subway.domain.path.PathFinder; +import subway.domain.path.SectionEdge; + +public class JgraphtPathFinder implements PathFinder { + + private final Subway subway; + + public JgraphtPathFinder(final Subway subway) { + this.subway = subway; + } + + @Override + public Path find(final String start, final String end) { + final DijkstraShortestPath shortestPath = initializeShortestPath(); + final GraphPath path = shortestPath.getPath(start, end); + return new JgraphtPath(path.getEdgeList()); + } + + private DijkstraShortestPath initializeShortestPath() { + final WeightedMultigraph graph = new WeightedMultigraph<>(SectionEdge.class); + addVertex(graph); + addEdge(graph); + return new DijkstraShortestPath<>(graph); + } + + private void addVertex(final WeightedMultigraph graph) { + subway.getStations().stream() + .map(Station::getName) + .forEach(graph::addVertex); + } + + private void addEdge(final WeightedMultigraph graph) { + for (final Line line : subway.getLines()) { + addEdgeByLine(graph, line); + } + } + + private void addEdgeByLine(final WeightedMultigraph graph, final Line line) { + for (final Section section : line.getSections()) { + final SectionEdge sectionEdge = new JgraphtSectionEdge(section, line.getSurcharge(), line.getId()); + graph.addEdge(section.getStartName(), section.getEndName(), sectionEdge); + graph.setEdgeWeight(sectionEdge, section.getDistanceValue()); + } + } +} diff --git a/src/main/java/subway/jgraph/JgraphtSectionEdge.java b/src/main/java/subway/jgraph/JgraphtSectionEdge.java new file mode 100644 index 000000000..4e045c617 --- /dev/null +++ b/src/main/java/subway/jgraph/JgraphtSectionEdge.java @@ -0,0 +1,33 @@ +package subway.jgraph; + +import org.jgrapht.graph.DefaultWeightedEdge; +import subway.domain.core.Section; +import subway.domain.path.SectionEdge; + +public class JgraphtSectionEdge extends DefaultWeightedEdge implements SectionEdge { + + private final Section section; + private final int surcharge; + private final long lineId; + + public JgraphtSectionEdge(final Section section, final int surcharge, final long lineId) { + this.section = section; + this.surcharge = surcharge; + this.lineId = lineId; + } + + @Override + public Section toSection() { + return section; + } + + @Override + public int getSurcharge() { + return surcharge; + } + + @Override + public long getLineId() { + return lineId; + } +} diff --git a/src/main/java/subway/service/PathService.java b/src/main/java/subway/service/PathService.java index 27e10982b..d5bae7a51 100644 --- a/src/main/java/subway/service/PathService.java +++ b/src/main/java/subway/service/PathService.java @@ -17,6 +17,7 @@ import subway.dto.ShortestPathRequest; import subway.dto.ShortestPathResponse; import subway.exception.LineNotFoundException; +import subway.jgraph.JgraphtPathFinder; import subway.repository.LineRepository; @Transactional(readOnly = true) @@ -33,7 +34,7 @@ public PathService(final LineRepository lineRepository, final FarePolicy farePol public ShortestPathResponse shortestPath(final ShortestPathRequest request) { final Subway subway = new Subway(lineRepository.findAll()); - final PathFinder pathFinder = new PathFinder(subway); + final PathFinder pathFinder = new JgraphtPathFinder(subway); final Path path = pathFinder.find(request.getStart(), request.getEnd()); final int fare = farePolicy.calculate(path, new Passenger(request.getAge()), 0); return new ShortestPathResponse(toLineDtos(path.getSectionEdges()), path.calculateTotalDistance(), fare); diff --git a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java index e78e35dae..f7a077ac8 100644 --- a/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/AgeDiscountFarePolicyTest.java @@ -1,8 +1,8 @@ package subway.domain.fare; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; -import java.util.Collections; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; @@ -17,7 +17,7 @@ class AgeDiscountFarePolicyTest { @Test void ์„ฑ์ธ์˜_๊ฒฝ์šฐ_ํ• ์ธ์ด_์ ์šฉ๋˜์ง€_์•Š๋Š”๋‹ค() { // given - final Path path = new Path(Collections.emptyList()); + final Path path = mock(Path.class); final Passenger passenger = new Passenger(19); final int fare = 1250; @@ -31,7 +31,7 @@ class AgeDiscountFarePolicyTest { @Test void ์ฒญ์†Œ๋…„์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_20ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { // given - final Path path = new Path(Collections.emptyList()); + final Path path = mock(Path.class); final Passenger passenger = new Passenger(18); final int fare = 1250; @@ -44,7 +44,7 @@ class AgeDiscountFarePolicyTest { @Test void ์–ด๋ฆฐ์ด์˜_๊ฒฝ์šฐ_350์›์„_ํ• ์ธํ•œ_๊ธˆ์•ก์—์„œ_50ํผ์„ผํŠธ๊ฐ€_ํ• ์ธ๋œ๋‹ค() { - final Path path = new Path(Collections.emptyList()); + final Path path = mock(Path.class); final Passenger passenger = new Passenger(6); final int fare = 1250; @@ -57,7 +57,7 @@ class AgeDiscountFarePolicyTest { @Test void ์œ ์•„์˜_๊ฒฝ์šฐ_๋ฌด๋ฃŒ๋‹ค() { - final Path path = new Path(Collections.emptyList()); + final Path path = mock(Path.class); final Passenger passenger = new Passenger(5); final int fare = 1250; diff --git a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java index 3e1ea8309..a29adbbe9 100644 --- a/src/test/java/subway/domain/fare/BaseFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/BaseFarePolicyTest.java @@ -1,8 +1,9 @@ package subway.domain.fare; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; -import java.util.Collections; import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; @@ -20,7 +21,7 @@ class BaseFarePolicyTest { @Test void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›์„_๋”ํ•œ๊ฐ’์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Path path = new Path(Collections.emptyList()); + final Path path = mock(Path.class); final Passenger passenger = new Passenger(20); // when @@ -33,11 +34,11 @@ class BaseFarePolicyTest { @Test void ๊ธฐ๋ณธ์šด์ž„์€_์ž…๋ ฅ๋ฐ›์€_์šด์ž„์—_1250์›๊ณผ_๋…ธ์„ ์šด์ž„_์ค‘_๊ฐ€์žฅ๋†’์€_๊ฐ’์„_๋”ํ•˜์—ฌ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 5), 100, 1), - new SectionEdge(new Section("B", "C", 10), 100, 1), - new SectionEdge(new Section("C", "T", 10), 300, 2), - new SectionEdge(new Section("T", "D", 10), 100, 1) + final Path path = mock(Path.class); + given(path.getSectionEdges()).willReturn(List.of( + generateSectionEdgeStub(100), + generateSectionEdgeStub(300), + generateSectionEdgeStub(100) )); final Passenger passenger = new Passenger(20); @@ -47,4 +48,23 @@ class BaseFarePolicyTest { // then assertThat(result).isEqualTo(1550); } + + private SectionEdge generateSectionEdgeStub(final int surcharge) { + return new SectionEdge() { + @Override + public Section toSection() { + return null; + } + + @Override + public int getSurcharge() { + return surcharge; + } + + @Override + public long getLineId() { + return 0; + } + }; + } } diff --git a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java index 5efc15894..c80e2fc7a 100644 --- a/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/DistanceFarePolicyTest.java @@ -1,14 +1,13 @@ package subway.domain.fare; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; -import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; -import subway.domain.core.Section; import subway.domain.path.Path; -import subway.domain.path.SectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @@ -19,10 +18,8 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_๋ฐœ์ƒํ•˜์ง€_์•Š๋Š”๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 4), 100, 1), - new SectionEdge(new Section("B", "C", 5), 100, 1) - )); + final Path path = mock(Path.class); + given(path.calculateTotalDistance()).willReturn(10); final Passenger passenger = new Passenger(20); // when @@ -35,10 +32,8 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_10ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๊ณ _50ํ‚ค๋กœ_์ดํ•˜์ธ_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_5KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 20), 100, 1), - new SectionEdge(new Section("B", "C", 7), 100, 1) - )); + final Path path = mock(Path.class); + given(path.calculateTotalDistance()).willReturn(27); final Passenger passenger = new Passenger(20); // when @@ -51,10 +46,8 @@ class DistanceFarePolicyTest { @Test void ์ž…๋ ฅ๋ฐ›์€_๊ฑฐ๋ฆฌ๊ฐ€_50ํ‚ค๋กœ๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_๊ฒฝ์šฐ_์ถ”๊ฐ€์šด์ž„์ด_8KM๋‹น_100์›์ด_๋ฐœ์ƒํ•œ๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 60), 100, 1), - new SectionEdge(new Section("B", "C", 1), 100, 1) - )); + final Path path = mock(Path.class); + given(path.calculateTotalDistance()).willReturn(61); final Passenger passenger = new Passenger(20); // when diff --git a/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java index d56abad79..5ceaa1c91 100644 --- a/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java +++ b/src/test/java/subway/domain/fare/SubwayFarePolicyTest.java @@ -1,6 +1,8 @@ package subway.domain.fare; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; import java.util.List; import org.junit.jupiter.api.DisplayNameGeneration; @@ -23,11 +25,12 @@ class SubwayFarePolicyTest { @Test void ์ตœ์ข…_์šด์ž„์„_๊ณ„์‚ฐํ•œ๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 5), 300, 1), - new SectionEdge(new Section("B", "C", 10), 300, 1), - new SectionEdge(new Section("C", "T", 10), 500, 2), - new SectionEdge(new Section("T", "D", 10), 300, 1) + final Path path = mock(Path.class); + given(path.calculateTotalDistance()).willReturn(35); + given(path.getSectionEdges()).willReturn(List.of( + generateSectionEdgeStub(100), + generateSectionEdgeStub(500), + generateSectionEdgeStub(100) )); final Passenger passenger = new Passenger(17); @@ -37,4 +40,23 @@ class SubwayFarePolicyTest { // then assertThat(result).isEqualTo(1520); } + + private SectionEdge generateSectionEdgeStub(final int surcharge) { + return new SectionEdge() { + @Override + public Section toSection() { + return null; + } + + @Override + public int getSurcharge() { + return surcharge; + } + + @Override + public long getLineId() { + return 0; + } + }; + } } diff --git a/src/test/java/subway/domain/path/PathFinderTest.java b/src/test/java/subway/jgrapht/JgraphtPathFinderTest.java similarity index 85% rename from src/test/java/subway/domain/path/PathFinderTest.java rename to src/test/java/subway/jgrapht/JgraphtPathFinderTest.java index 239b2e4c1..25b933860 100644 --- a/src/test/java/subway/domain/path/PathFinderTest.java +++ b/src/test/java/subway/jgrapht/JgraphtPathFinderTest.java @@ -1,4 +1,4 @@ -package subway.domain.path; +package subway.jgrapht; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; @@ -10,10 +10,14 @@ import subway.domain.core.Line; import subway.domain.core.Section; import subway.domain.core.Subway; +import subway.domain.path.Path; +import subway.domain.path.PathFinder; +import subway.domain.path.SectionEdge; +import subway.jgraph.JgraphtPathFinder; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class PathFinderTest { +class JgraphtPathFinderTest { @Test void ์ตœ๋‹จ_๊ฒฝ๋กœ๋ฅผ_ํƒ์ƒ‰ํ•œ๋‹ค() { @@ -28,7 +32,7 @@ class PathFinderTest { new Section("B", "Y", 5) )) )); - final PathFinder pathFinder = new PathFinder(subway); + final PathFinder pathFinder = new JgraphtPathFinder(subway); // when final Path path = pathFinder.find("A", "Y"); diff --git a/src/test/java/subway/domain/path/PathTest.java b/src/test/java/subway/jgrapht/JgraphtPathTest.java similarity index 54% rename from src/test/java/subway/domain/path/PathTest.java rename to src/test/java/subway/jgrapht/JgraphtPathTest.java index 1f8159b71..560651a9f 100644 --- a/src/test/java/subway/domain/path/PathTest.java +++ b/src/test/java/subway/jgrapht/JgraphtPathTest.java @@ -1,4 +1,4 @@ -package subway.domain.path; +package subway.jgrapht; import static org.assertj.core.api.Assertions.assertThat; @@ -7,19 +7,22 @@ import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; import subway.domain.core.Section; +import subway.domain.path.Path; +import subway.jgraph.JgraphtPath; +import subway.jgraph.JgraphtSectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class PathTest { +class JgraphtPathTest { @Test void ๊ฒฝ๋กœ์˜_์ด_๊ฑฐ๋ฆฌ๋ฅผ_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final Path path = new Path(List.of( - new SectionEdge(new Section("A", "B", 2), 300, 1), - new SectionEdge(new Section("B", "C", 5), 300, 1), - new SectionEdge(new Section("C", "T", 7), 500, 2), - new SectionEdge(new Section("T", "D", 4), 300, 1) + final Path path = new JgraphtPath(List.of( + new JgraphtSectionEdge(new Section("A", "B", 2), 300, 1), + new JgraphtSectionEdge(new Section("B", "C", 5), 300, 1), + new JgraphtSectionEdge(new Section("C", "T", 7), 500, 2), + new JgraphtSectionEdge(new Section("T", "D", 4), 300, 1) )); // when diff --git a/src/test/java/subway/domain/path/SectionEdgeTest.java b/src/test/java/subway/jgrapht/JgraphtSectionEdgeTest.java similarity index 71% rename from src/test/java/subway/domain/path/SectionEdgeTest.java rename to src/test/java/subway/jgrapht/JgraphtSectionEdgeTest.java index a91bffbfc..21fb3e155 100644 --- a/src/test/java/subway/domain/path/SectionEdgeTest.java +++ b/src/test/java/subway/jgrapht/JgraphtSectionEdgeTest.java @@ -1,4 +1,4 @@ -package subway.domain.path; +package subway.jgrapht; import static org.assertj.core.api.Assertions.assertThat; @@ -6,15 +6,17 @@ import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; import subway.domain.core.Section; +import subway.domain.path.SectionEdge; +import subway.jgraph.JgraphtSectionEdge; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") -class SectionEdgeTest { +class JgraphtSectionEdgeTest { @Test void Section์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() { // given - final SectionEdge sectionEdge = new SectionEdge(new Section("A", "B", 5), 500, 1); + final SectionEdge sectionEdge = new JgraphtSectionEdge(new Section("A", "B", 5), 500, 1); // when final Section result = sectionEdge.toSection(); From d94cbd7efda105d6a4a9eb14c8d2c6fef02ff65e Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 17:21:51 +0900 Subject: [PATCH 37/38] =?UTF-8?q?refactor:=20Enum=20String=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/domain/core/Subway.java | 3 ++- src/main/java/subway/dto/StationSaveRequest.java | 7 +++---- src/test/java/subway/common/steps/SectionSteps.java | 7 +++---- src/test/java/subway/controller/StationControllerTest.java | 3 +-- src/test/java/subway/domain/core/SubwayTest.java | 7 +++---- src/test/java/subway/service/StationServiceTest.java | 3 +-- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/main/java/subway/domain/core/Subway.java b/src/main/java/subway/domain/core/Subway.java index 8280ded5f..2a46765dc 100644 --- a/src/main/java/subway/domain/core/Subway.java +++ b/src/main/java/subway/domain/core/Subway.java @@ -21,11 +21,12 @@ public void add( final String baseStationName, final String additionalStationName, final int distanceValue, - final Direction direction + final String directionValue ) { final Station base = new Station(baseStationName); final Station additional = new Station(additionalStationName); final Distance distance = new Distance(distanceValue); + final Direction direction = Direction.valueOf(directionValue); if (lines.stream().anyMatch(line -> line.containsAll(base, additional))) { throw new InvalidSectionException("์ง€ํ•˜์ฒ  ์ „์ฒด ๋…ธ์„ ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค."); diff --git a/src/main/java/subway/dto/StationSaveRequest.java b/src/main/java/subway/dto/StationSaveRequest.java index 1d347d452..c0e459170 100644 --- a/src/main/java/subway/dto/StationSaveRequest.java +++ b/src/main/java/subway/dto/StationSaveRequest.java @@ -3,7 +3,6 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Positive; -import subway.domain.core.Direction; public class StationSaveRequest { @@ -17,7 +16,7 @@ public class StationSaveRequest { private final String additionalStationName; @NotNull(message = "์™ผ์ชฝ์œผ๋กœ ๋“ฑ๋กํ•  ๊ฒฝ์šฐ LEFT, ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋“ฑ๋กํ•  ๊ฒฝ์šฐ RIGHT๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") - private final Direction direction; + private final String direction; @Positive(message = "๋“ฑ๋กํ•  ๊ฑฐ๋ฆฌ๋Š” ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") private final Integer distance; @@ -26,7 +25,7 @@ public StationSaveRequest( final String lineName, final String baseStationName, final String additionalStationName, - final Direction direction, + final String direction, final Integer distance ) { this.lineName = lineName; @@ -48,7 +47,7 @@ public String getAdditionalStationName() { return additionalStationName; } - public Direction getDirection() { + public String getDirection() { return direction; } diff --git a/src/test/java/subway/common/steps/SectionSteps.java b/src/test/java/subway/common/steps/SectionSteps.java index 21232231c..eeca0ba48 100644 --- a/src/test/java/subway/common/steps/SectionSteps.java +++ b/src/test/java/subway/common/steps/SectionSteps.java @@ -4,7 +4,6 @@ import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.springframework.http.MediaType; -import subway.domain.core.Direction; import subway.domain.core.Section; import subway.dto.StationDeleteRequest; import subway.dto.StationInitialSaveRequest; @@ -13,8 +12,8 @@ @SuppressWarnings("NonAsciiCharacters") public class SectionSteps { - public static final Direction ์™ผ์ชฝ = Direction.LEFT; - public static final Direction ์˜ค๋ฅธ์ชฝ = Direction.RIGHT; + public static final String ์™ผ์ชฝ = "LEFT"; + public static final String ์˜ค๋ฅธ์ชฝ = "RIGHT"; public static ExtractableResponse ๋…ธ์„ ์—_๊ตฌ๊ฐ„์ด_์กด์žฌํ•˜์ง€_์•Š์„_๋•Œ_์ดˆ๊ธฐ_๊ตฌ๊ฐ„_์ƒ์„ฑ_์š”์ฒญ( final String ๋…ธ์„ ๋ช…, @@ -37,7 +36,7 @@ public class SectionSteps { final String ๋…ธ์„ ๋ช…, final String ๊ธฐ์ค€์—ญ, final String ์ถ”๊ฐ€์—ญ, - final Direction ๋ฐฉํ–ฅ, + final String ๋ฐฉํ–ฅ, final int ๊ฑฐ๋ฆฌ ) { final StationSaveRequest request = new StationSaveRequest(๋…ธ์„ ๋ช…, ๊ธฐ์ค€์—ญ, ์ถ”๊ฐ€์—ญ, ๋ฐฉํ–ฅ, ๊ฑฐ๋ฆฌ); diff --git a/src/test/java/subway/controller/StationControllerTest.java b/src/test/java/subway/controller/StationControllerTest.java index 01b73bc6d..3fa8412f2 100644 --- a/src/test/java/subway/controller/StationControllerTest.java +++ b/src/test/java/subway/controller/StationControllerTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import static subway.domain.core.Direction.RIGHT; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; @@ -33,7 +32,7 @@ public class StationControllerTest extends IntegrationTest { lineRepository.save(new Line("1ํ˜ธ์„ ", "RED", 0, List.of( new Section("A", "B", 2) ))); - final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", RIGHT, 3); + final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", "RIGHT", 3); // when ExtractableResponse response = RestAssured diff --git a/src/test/java/subway/domain/core/SubwayTest.java b/src/test/java/subway/domain/core/SubwayTest.java index a9e8dd011..bc4a4ec02 100644 --- a/src/test/java/subway/domain/core/SubwayTest.java +++ b/src/test/java/subway/domain/core/SubwayTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static subway.domain.core.Direction.LEFT; import java.util.Collections; import java.util.List; @@ -32,7 +31,7 @@ class SubwayTest { final Subway subway = new Subway(List.of(line1, line2)); // expect - assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, LEFT)) + assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, "LEFT")) .isInstanceOf(InvalidSectionException.class) .hasMessage("์ง€ํ•˜์ฒ  ์ „์ฒด ๋…ธ์„ ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค."); } @@ -43,7 +42,7 @@ class SubwayTest { final Subway subway = new Subway(Collections.emptyList()); // expect - assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, LEFT)) + assertThatThrownBy(() -> subway.add("1ํ˜ธ์„ ", "B", "Y", 5, "LEFT")) .isInstanceOf(LineNotFoundException.class) .hasMessage("๋…ธ์„ ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); } @@ -63,7 +62,7 @@ class SubwayTest { )); // when - subway.add("1ํ˜ธ์„ ", "B", "D", 3, LEFT); + subway.add("1ํ˜ธ์„ ", "B", "D", 3, "LEFT"); // then assertThat(subway.getLines()).flatExtracting(Line::getSections).containsAll(List.of( diff --git a/src/test/java/subway/service/StationServiceTest.java b/src/test/java/subway/service/StationServiceTest.java index 67bf44336..861cce6d1 100644 --- a/src/test/java/subway/service/StationServiceTest.java +++ b/src/test/java/subway/service/StationServiceTest.java @@ -1,7 +1,6 @@ package subway.service; import static org.assertj.core.api.Assertions.assertThat; -import static subway.domain.core.Direction.RIGHT; import java.util.Collections; import java.util.List; @@ -40,7 +39,7 @@ public class StationServiceTest { new Section("Z", "B", 2), new Section("B", "Y", 3) ))); - final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", RIGHT, 3); + final StationSaveRequest request = new StationSaveRequest("1ํ˜ธ์„ ", "B", "C", "RIGHT", 3); // when stationService.save(request); From 4d42c469ddf1c13c9bd36e7ff23dc6f9597a5c9f Mon Sep 17 00:00:00 2001 From: greeng00se Date: Sun, 21 May 2023 18:14:23 +0900 Subject: [PATCH 38/38] =?UTF-8?q?chore:=20DB=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...a => ProductionDatabaseConfiguration.java} | 4 ++- .../config/TestDatabaseConfiguration.java | 22 ++++++++++++++ src/main/resources/application.yml | 6 +++- src/test/resources/application.yml | 9 ++---- src/test/resources/schema.sql | 30 +++++++++++++++++++ 5 files changed, 63 insertions(+), 8 deletions(-) rename src/main/java/subway/config/{DatabaseConfiguration.java => ProductionDatabaseConfiguration.java} (87%) create mode 100644 src/main/java/subway/config/TestDatabaseConfiguration.java create mode 100644 src/test/resources/schema.sql diff --git a/src/main/java/subway/config/DatabaseConfiguration.java b/src/main/java/subway/config/ProductionDatabaseConfiguration.java similarity index 87% rename from src/main/java/subway/config/DatabaseConfiguration.java rename to src/main/java/subway/config/ProductionDatabaseConfiguration.java index 008efd636..1d8be6200 100644 --- a/src/main/java/subway/config/DatabaseConfiguration.java +++ b/src/main/java/subway/config/ProductionDatabaseConfiguration.java @@ -5,9 +5,11 @@ import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +@Profile("prod") @Configuration -public class DatabaseConfiguration { +public class ProductionDatabaseConfiguration { @Value("${my.datasource.url}") private String url; diff --git a/src/main/java/subway/config/TestDatabaseConfiguration.java b/src/main/java/subway/config/TestDatabaseConfiguration.java new file mode 100644 index 000000000..451a3f54a --- /dev/null +++ b/src/main/java/subway/config/TestDatabaseConfiguration.java @@ -0,0 +1,22 @@ +package subway.config; + +import javax.sql.DataSource; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Profile("test") +@Configuration +public class TestDatabaseConfiguration { + + @Bean + public DataSource dataSource() { + return DataSourceBuilder.create() + .url("jdbc:h2:mem:test") + .driverClassName("org.h2.Driver") + .username("sa") + .password("") + .build(); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cdfe6e9a4..771a2401f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,10 @@ my: datasource: - url: ${DB_URL:jdbc:h2:mem:test} + url: ${DB_URL:jdbc:h2:mem:prod} username: ${DB_USERNAME:sa} password: ${DB_PASSWORD:} driver-class-name: ${DB_DRIVER:org.h2.Driver} + +spring: + profiles: + active: prod diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index f414b6fa7..03c30d374 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,6 +1,3 @@ -my: - datasource: - url: jdbc:h2:mem:test - username: sa - password: - driver-class-name: org.h2.Driver +spring: + profiles: + active: test diff --git a/src/test/resources/schema.sql b/src/test/resources/schema.sql new file mode 100644 index 000000000..c1722432d --- /dev/null +++ b/src/test/resources/schema.sql @@ -0,0 +1,30 @@ +CREATE TABLE IF NOT EXISTS LINE +( + id BIGINT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) UNIQUE NOT NULL, + color VARCHAR(20) NOT NULL, + surcharge INT NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS STATION +( + id BIGINT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) NOT NULL, + line_id BIGINT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (line_id) REFERENCES LINE (id) +); + +CREATE TABLE IF NOT EXISTS SECTION +( + id BIGINT AUTO_INCREMENT NOT NULL, + start_station_id BIGINT NOT NULL, + end_station_id BIGINT NOT NULL, + distance INT NOT NULL, + line_id BIGINT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (start_station_id) REFERENCES STATION (id), + FOREIGN KEY (end_station_id) REFERENCES STATION (id), + FOREIGN KEY (line_id) REFERENCES LINE (id) +);