From c0dc38b9545fc2d152bd98dbd25e8515c1744b07 Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 3 May 2024 22:18:15 +0900 Subject: [PATCH 1/8] =?UTF-8?q?docs:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/docs/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/docs/README.md diff --git a/src/main/java/docs/README.md b/src/main/java/docs/README.md new file mode 100644 index 000000000..9d16f8177 --- /dev/null +++ b/src/main/java/docs/README.md @@ -0,0 +1,33 @@ +# 기능정의 + +## 도메인 + +### 지하철(Staion) + +- [ ] 지하철역 등록 기능 + - [ ] [ERROR] 지하철역은 두글자 이상이여야 한다. + - [ ] [ERROR] 지하철역은 한국어만 가능합니다. + - [ ] [ERROR] 중복된 역 이름은 등록할 수 없습니다. +- [ ] 지하철역 삭제 기능 + - [ ] [ERROR] 존재하는 지하철역만 삭제 가능합니다. + - [ ] [ERROR] 노선에 등록된 역은 삭제가 안됩니다. +- [ ] 지하철역 전체 조회 기능 + +### 노선(Line) + +- [ ] 노선 등록 기능 + - [ ] 등록시 상행 종점과 하행 종점을 입력받는다. + - [ ] [ERROR] 노선의 이름은 두글자 이상이여야 한다. +- [ ] 노선 삭제 기능 + - [ ] [ERROR] 존재하는 노선만 삭제 가능합니다. +- [ ] 노선 목록 조회 기능 +- [ ] 노선에 등록된 역 조회 기능 + - [ ] 노선의 상행 종점부터 하행 종점까지 순서대로 목록을 조회한다. + +### 구간 + +- [ ] 존재하는 노선에 역을 추가한다. + - [ ] [ERROR] 등록된 역만 노선에 추가가 가능하다. +- [ ] 노선에 역을 삭제한다. + - [ ] [ERROR] 노선에 역이 2개 이하면 삭제할 수 없다. + - [ ] [ERROR] 노선에 존재하는 욕만 삭제할 수 있다. \ No newline at end of file From 3868abefaf0b7318d861d152c86aaa875fb92403 Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Wed, 8 May 2024 01:30:04 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/subway/Application.java | 6 +- .../java/subway/common/ExceptionHander.java | 13 ++ .../java/subway/constant/LineCommand.java | 25 ++++ .../java/subway/constant/MainCommand.java | 25 ++++ .../java/subway/constant/SectionCommand.java | 23 ++++ .../java/subway/constant/StationCommand.java | 24 ++++ .../subway/constant/message/ErrorMessage.java | 15 +++ .../constant/message/Processmessage.java | 16 +++ .../subway/controller/SubwayController.java | 116 ++++++++++++++++++ src/main/java/subway/domain/Line.java | 23 +++- .../java/subway/domain/LineRepository.java | 29 ++++- src/main/java/subway/domain/Station.java | 25 +++- .../java/subway/domain/StationRepository.java | 29 ++++- src/main/java/subway/domain/Subway.java | 36 ++++++ .../java/subway/service/SubwayService.java | 105 ++++++++++++++++ src/main/java/subway/view/InputView.java | 68 ++++++++++ src/main/java/subway/view/OutputView.java | 83 +++++++++++++ 17 files changed, 643 insertions(+), 18 deletions(-) create mode 100644 src/main/java/subway/common/ExceptionHander.java create mode 100644 src/main/java/subway/constant/LineCommand.java create mode 100644 src/main/java/subway/constant/MainCommand.java create mode 100644 src/main/java/subway/constant/SectionCommand.java create mode 100644 src/main/java/subway/constant/StationCommand.java create mode 100644 src/main/java/subway/constant/message/ErrorMessage.java create mode 100644 src/main/java/subway/constant/message/Processmessage.java create mode 100644 src/main/java/subway/controller/SubwayController.java create mode 100644 src/main/java/subway/domain/Subway.java create mode 100644 src/main/java/subway/service/SubwayService.java create mode 100644 src/main/java/subway/view/InputView.java create mode 100644 src/main/java/subway/view/OutputView.java diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..fb77e68cc 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,10 @@ package subway; -import java.util.Scanner; +import subway.controller.SubwayController; public class Application { public static void main(String[] args) { - final Scanner scanner = new Scanner(System.in); - // TODO: 프로그램 구현 + final SubwayController subwayController = new SubwayController(); + subwayController.start(); } } diff --git a/src/main/java/subway/common/ExceptionHander.java b/src/main/java/subway/common/ExceptionHander.java new file mode 100644 index 000000000..bf8d73e9f --- /dev/null +++ b/src/main/java/subway/common/ExceptionHander.java @@ -0,0 +1,13 @@ +package subway.common; + +public class ExceptionHander { + + public static void retryOnException(final Runnable runnable) { + try { + runnable.run(); + } catch (final IllegalArgumentException | IllegalStateException e) { + System.out.println(e.getMessage()); + retryOnException(runnable); + } + } +} diff --git a/src/main/java/subway/constant/LineCommand.java b/src/main/java/subway/constant/LineCommand.java new file mode 100644 index 000000000..eb124567e --- /dev/null +++ b/src/main/java/subway/constant/LineCommand.java @@ -0,0 +1,25 @@ +package subway.constant; + +import java.util.Arrays; +import subway.constant.message.ErrorMessage; + +public enum LineCommand { + + SAVE("1"), + DELETE("2"), + SELECT("3"), + BACK("B"); + + private final String command; + + LineCommand(final String command) { + this.command = command; + } + + public static LineCommand from(final String input) { + return Arrays.stream(LineCommand.values()) + .filter(e -> e.command.equals(input)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 버튼입니다.")); + } +} diff --git a/src/main/java/subway/constant/MainCommand.java b/src/main/java/subway/constant/MainCommand.java new file mode 100644 index 000000000..fddd95d19 --- /dev/null +++ b/src/main/java/subway/constant/MainCommand.java @@ -0,0 +1,25 @@ +package subway.constant; + +import java.util.Arrays; +import subway.constant.message.ErrorMessage; + +public enum MainCommand { + STATION_MANAGE("1"), + LINE_MANAGE("2"), + SECTION_MANAGE("3"), + PRINT_SUBWAY("4"), + QUIT("Q"); + + private final String command; + + MainCommand(final String command) { + this.command = command; + } + + public static MainCommand from(final String input) { + return Arrays.stream(MainCommand.values()) + .filter(e -> e.command.equalsIgnoreCase(input)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 버튼입니다.")); + } +} diff --git a/src/main/java/subway/constant/SectionCommand.java b/src/main/java/subway/constant/SectionCommand.java new file mode 100644 index 000000000..43eb5e251 --- /dev/null +++ b/src/main/java/subway/constant/SectionCommand.java @@ -0,0 +1,23 @@ +package subway.constant; + +import java.util.Arrays; +import subway.constant.message.ErrorMessage; + +public enum SectionCommand { + SAVE("1"), + DELETE("2"), + BACK("B"); + + private final String command; + + SectionCommand(final String command) { + this.command = command; + } + + public static SectionCommand from(final String input) { + return Arrays.stream(SectionCommand.values()) + .filter(e -> e.command.equals(input)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 버튼입니다.")); + } +} diff --git a/src/main/java/subway/constant/StationCommand.java b/src/main/java/subway/constant/StationCommand.java new file mode 100644 index 000000000..dcf75ef7b --- /dev/null +++ b/src/main/java/subway/constant/StationCommand.java @@ -0,0 +1,24 @@ +package subway.constant; + +import java.util.Arrays; +import subway.constant.message.ErrorMessage; + +public enum StationCommand { + SAVE("1"), + DELETE("2"), + SELECT("3"), + BACK("B"); + + private final String command; + + StationCommand(final String command) { + this.command = command; + } + + public static StationCommand from(final String input) { + return Arrays.stream(StationCommand.values()) + .filter(e -> e.command.equals(input)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 버튼입니다.")); + } +} diff --git a/src/main/java/subway/constant/message/ErrorMessage.java b/src/main/java/subway/constant/message/ErrorMessage.java new file mode 100644 index 000000000..f7b5a6639 --- /dev/null +++ b/src/main/java/subway/constant/message/ErrorMessage.java @@ -0,0 +1,15 @@ +package subway.constant.message; + +public enum ErrorMessage { + ERROR_PREFIX("[ERROR] "); + + private final String message; + + ErrorMessage(final String message) { + this.message = message; + } + + public String toMessage() { + return message; + } +} diff --git a/src/main/java/subway/constant/message/Processmessage.java b/src/main/java/subway/constant/message/Processmessage.java new file mode 100644 index 000000000..aed9eb789 --- /dev/null +++ b/src/main/java/subway/constant/message/Processmessage.java @@ -0,0 +1,16 @@ +package subway.constant.message; + +public enum Processmessage { + SUCCESS_PREFIX("[INFO] "), + ; + + private final String message; + + Processmessage(final String message) { + this.message = message; + } + + public String toMessage() { + return message; + } +} diff --git a/src/main/java/subway/controller/SubwayController.java b/src/main/java/subway/controller/SubwayController.java new file mode 100644 index 000000000..1e3460d7f --- /dev/null +++ b/src/main/java/subway/controller/SubwayController.java @@ -0,0 +1,116 @@ +package subway.controller; + +import java.util.List; +import subway.common.ExceptionHander; +import subway.constant.LineCommand; +import subway.constant.MainCommand; +import subway.constant.SectionCommand; +import subway.constant.StationCommand; +import subway.domain.Subway; +import subway.service.SubwayService; +import subway.view.InputView; +import subway.view.OutputView; + +public class SubwayController { + + private final OutputView outputView = new OutputView(); + private final InputView inputView = new InputView(); + private final SubwayService subwayService = new SubwayService(); + + public void start() { + subwayService.initializeSubway(); + ExceptionHander.retryOnException(this::startSubway); + } + + private void startSubway() { + while (true) { + outputView.printMainView(); + final String command = inputView.readCommand(); + final MainCommand mainCommand = MainCommand.from(command); + if (mainCommand.equals(MainCommand.STATION_MANAGE)) { + manageStation(); + } + if (mainCommand.equals(MainCommand.LINE_MANAGE)) { + manageLine(); + } + if (mainCommand.equals(MainCommand.SECTION_MANAGE)) { + manageSection(); + } + if (mainCommand.equals(MainCommand.PRINT_SUBWAY)) { + final Subway subway = subwayService.getSubway(); + outputView.printSubway(subway); + } + } + } + + private void manageSection() { + while (true) { + outputView.printSectionManageView(); + final String sectionManageCommand = inputView.readCommand(); + final SectionCommand sectionCommand = SectionCommand.from(sectionManageCommand); + if (sectionCommand.equals(SectionCommand.SAVE)) { + final String inputLine = inputView.readLineName(); + final String inputStation = inputView.readStationName(); + final String inputIndex = inputView.readStationInputIndex(); + subwayService.addSubwayStation(inputLine, inputStation, inputIndex); + } + if (sectionCommand.equals(SectionCommand.DELETE)) { + final String inputLine = inputView.readDeleteLineName(); + subwayService.deleteSubwayLine(inputLine); + } + if (sectionCommand.equals(SectionCommand.BACK)) { + break; + } + } + } + + private void manageLine() { + while (true) { + outputView.printLineManageView(); + final String lineManageCommand = inputView.readCommand(); + final LineCommand lineCommand = LineCommand.from(lineManageCommand); + if (lineCommand.equals(LineCommand.SAVE)) { + final String inputName = inputView.readSaveLineName(); + final String inputLineStartStationName = inputView.readLineStartStationName(); + final String inputLineEndStationName = inputView.readLineEndStatationName(); + subwayService.saveLine(inputName, inputLineStartStationName, inputLineEndStationName); + outputView.printSubwayAddSuccess(); + } + if (lineCommand.equals(LineCommand.DELETE)) { + final String inputLineName = inputView.readDeleteLineName(); + subwayService.deleteLine(inputLineName); + outputView.printSubwayDeleteSuccess(); + } + if (lineCommand.equals(LineCommand.SELECT)) { + List lineNames = subwayService.getAllLine(); + outputView.printLines(lineNames); + } + if (lineCommand.equals(LineCommand.BACK)) { + break; + } + } + } + + private void manageStation() { + while (true) { + outputView.printStationManageView(); + final String stationManageCommand = inputView.readCommand(); + final StationCommand stationCommand = StationCommand.from(stationManageCommand); + if (stationCommand.equals(StationCommand.SAVE)) { + final String input = inputView.readSaveStationName(); + subwayService.saveStation(input); + } + if (stationCommand.equals(StationCommand.DELETE)) { + final String input = inputView.readDeleteStationName(); + subwayService.deleteStation(input); + } + if (stationCommand.equals(StationCommand.SELECT)) { + final List stationsName = subwayService.getAllStations(); + outputView.printStations(stationsName); + } + if (stationCommand.equals(StationCommand.BACK)) { + break; + } + } + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index f4d738d5a..523ba685e 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,5 +1,7 @@ package subway.domain; +import java.util.Objects; + public class Line { private String name; @@ -11,5 +13,24 @@ public String getName() { return name; } - // 추가 기능 구현 + public boolean isEqualsByName(final String input) { + return Objects.equals(name, input); + } + + @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(getName(), line.getName()); + } + + @Override + public int hashCode() { + return Objects.hash(getName()); + } } diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 49132ddb6..5680977b7 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -3,20 +3,37 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; +import subway.constant.message.ErrorMessage; public class LineRepository { - private static final List lines = new ArrayList<>(); + private final List lines = new ArrayList<>(); - public static List lines() { + public List getAll() { return Collections.unmodifiableList(lines); } - public static void addLine(Line line) { + public void save(final Line line) { + if (lines.stream() + .anyMatch(element -> element.equals(line))) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "중복된 호선은 입력될 수 없습니다."); + } lines.add(line); } - public static boolean deleteLineByName(String name) { - return lines.removeIf(line -> Objects.equals(line.getName(), name)); + public void delete(final String name) { + if (!deleteLine(name)) { + throw new IllegalStateException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 호선을 입력했습니다."); + } + } + + private boolean deleteLine(final String name) { + return lines.removeIf(station -> station.isEqualsByName(name)); + } + + public Line getByName(final String name) { + return lines.stream() + .filter(e -> e.isEqualsByName(name)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("이름에 해당하는 노선이 없습니다.")); } } diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index bdb142590..34d5a666a 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -1,9 +1,11 @@ package subway.domain; +import java.util.Objects; + public class Station { private String name; - public Station(String name) { + public Station(final String name) { this.name = name; } @@ -11,5 +13,24 @@ public String getName() { return name; } - // 추가 기능 구현 + public boolean isEqualsByName(final String input) { + return Objects.equals(name, input); + } + + @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(getName(), station.getName()); + } + + @Override + public int hashCode() { + return Objects.hash(getName()); + } } diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java index b7245c0f3..129a65cf5 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/StationRepository.java @@ -3,20 +3,37 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; +import subway.constant.message.ErrorMessage; public class StationRepository { - private static final List stations = new ArrayList<>(); + private final List stations = new ArrayList<>(); - public static List stations() { + public List getAll() { return Collections.unmodifiableList(stations); } - public static void addStation(Station station) { + public void save(final Station station) { + if (stations.stream() + .anyMatch(element -> element.equals(station))) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "중복된 지하철역은 입력될 수 없습니다."); + } stations.add(station); } - public static boolean deleteStation(String name) { - return stations.removeIf(station -> Objects.equals(station.getName(), name)); + public void delete(final String name) { + if (!deleteStation(name)) { + throw new IllegalStateException(ErrorMessage.ERROR_PREFIX.toMessage() + "없는 역을 입력했습니다."); + } + } + + private boolean deleteStation(final String name) { + return stations.removeIf(station -> station.isEqualsByName(name)); + } + + public Station getByName(final String name) { + return stations.stream() + .filter(e -> e.isEqualsByName(name)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("이름에 해당하는 역이 없습니다.")); } } diff --git a/src/main/java/subway/domain/Subway.java b/src/main/java/subway/domain/Subway.java new file mode 100644 index 000000000..a0e6d4009 --- /dev/null +++ b/src/main/java/subway/domain/Subway.java @@ -0,0 +1,36 @@ +package subway.domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Subway { + + private static final int INDEX_ADDER = 1; + private final Map> subway; + + public Subway() { + this.subway = new HashMap<>(); + } + + public Map> getSubway() { + return subway; + } + + public void addNewSubwayLine(final Line line, final List stations) { + subway.put(line, stations); + } + + public void deleteSubwayByLine(final Line line) { + subway.remove(line); + } + + public void addStationByLine(final Line line, final Station station, final int stationIndex) { + List stations = subway.get(line); + if (stations.stream().anyMatch(e -> e.equals(station))) { + throw new IllegalArgumentException("중복된 값을 저장할 수 없습니다."); + } + stations.add(stationIndex + INDEX_ADDER, station); + + } +} diff --git a/src/main/java/subway/service/SubwayService.java b/src/main/java/subway/service/SubwayService.java new file mode 100644 index 000000000..6023c9f4c --- /dev/null +++ b/src/main/java/subway/service/SubwayService.java @@ -0,0 +1,105 @@ +package subway.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import subway.domain.Line; +import subway.domain.LineRepository; +import subway.domain.Station; +import subway.domain.StationRepository; +import subway.domain.Subway; + +public class SubwayService { + + + private final Subway subway = new Subway(); + private final LineRepository lineRepository = new LineRepository(); + private final StationRepository stationRepository = new StationRepository(); + + public void saveStation(final String input) { + final Station station = new Station(input); + stationRepository.save(station); + } + + public void deleteStation(final String input) { + stationRepository.delete(input); + } + + + public void saveAllStations(final List inputs) { + List stations = inputs.stream() + .map(Station::new) + .collect(Collectors.toList()); + stations.forEach(stationRepository::save); + } + + public void saveAllLines(final List inputs) { + List lines = inputs.stream() + .map(Line::new) + .collect(Collectors.toList()); + lines.forEach(lineRepository::save); + } + + public void saveAllSubway(final Map> subwayMaps) { + for (Map.Entry> entry : subwayMaps.entrySet()) { + Line line = new Line(entry.getKey()); + List stations = entry.getValue().stream() + .map(Station::new) + .collect(Collectors.toList()); + subway.getSubway().put(line, stations); + } + } + + public void initializeSubway() { + List stations = List.of("교대역", "강남역", "역삼역", "남부터미널역", "양재역", "양재시민의숲역", "매봉역"); + saveAllStations(stations); + List lines = List.of("2호선", "3호선", "신분당선"); + saveAllLines(lines); + Map> map = new HashMap<>(); + map.put("2호선", List.of("교대역", "강남역", "역삼역")); + map.put("3호선", List.of("교대역", "남부터미널역", "양재역", "매봉역")); + map.put("신분당선", List.of("강남역", "양재역", "양재시민의숲역")); + saveAllSubway(map); + } + + public List getAllStations() { + return stationRepository.getAll().stream() + .map(Station::getName) + .collect(Collectors.toList()); + } + + public void saveLine(final String lineName, final String startStationName, final String endStationName) { + final Station startStation = stationRepository.getByName(startStationName); + final Station endStation = stationRepository.getByName(endStationName); + final Line line = lineRepository.getByName(lineName); + subway.addNewSubwayLine(line, List.of(startStation, endStation)); + } + + public void deleteLine(final String lineName) { + lineRepository.delete(lineName); + } + + public List getAllLine() { + return lineRepository.getAll().stream() + .map(Line::getName) + .collect(Collectors.toList()); + } + + public void addSubwayStation(final String inputLine, final String inputStation, final String inputIndex) { + final Line line = lineRepository.getByName(inputLine); + final Station station = stationRepository.getByName(inputStation); + final int stationIndex = Integer.parseInt(inputIndex); + subway.addStationByLine(line, station, stationIndex); + } + + public void deleteSubwayLine(final String inputLine) { + final Line line = lineRepository.getByName(inputLine); + subway.deleteSubwayByLine(line); + } + + public Subway getSubway() { + return subway; + } +} + diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java new file mode 100644 index 000000000..26026cc72 --- /dev/null +++ b/src/main/java/subway/view/InputView.java @@ -0,0 +1,68 @@ +package subway.view; + +import java.util.Scanner; + +public class InputView { + + private static final Scanner scanner = new Scanner(System.in); + + public String readCommand() { + System.out.println("## 원하는 기능을 선택하세요."); + final String command = scanner.next(); + return command; + } + + public String readSaveStationName() { + System.out.println("## 등록할 역 이름을 입력하세요."); + final String input = scanner.next(); + return input; + + } + + public String readDeleteStationName() { + System.out.println("## 삭제할 역 이름을 입력하세요."); + final String input = scanner.next(); + return input; + } + + public String readSaveLineName() { + System.out.println("## 등록할 노선 이름을 입력하세요."); + final String input = scanner.next(); + return input; + } + public String readDeleteLineName() { + System.out.println("## 삭제할 노선 이름을 입력하세요."); + final String input = scanner.next(); + return input; + } + + public String readLineStartStationName() { + System.out.println("## 등록할 노선의 상행 종점역 이름을 입력하세요."); + final String input = scanner.next(); + return input; + } + + public String readLineEndStatationName() { + System.out.println("## 등록할 노선의 하행 종점역 이름을 입력하세요."); + final String input = scanner.next(); + return input; + } + + public String readLineName() { + System.out.println("## 노선을 입력하세요.\n"); + final String input = scanner.next(); + return input; + } + + public String readStationName() { + System.out.println("## 역이름을 입력하세요.\n"); + final String input = scanner.next(); + return input; + } + + public String readStationInputIndex() { + System.out.println("## 순서를 입력하세요.\n"); + final String input = scanner.next(); + return input; + } +} diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java new file mode 100644 index 000000000..cb91e80d2 --- /dev/null +++ b/src/main/java/subway/view/OutputView.java @@ -0,0 +1,83 @@ +package subway.view; + +import java.util.List; +import java.util.Map.Entry; +import subway.constant.message.Processmessage; +import subway.domain.Line; +import subway.domain.Station; +import subway.domain.Subway; + +public class OutputView { + + public void printMainView() { + System.out.println("## 메인 화면\n" + + "1. 역 관리\n" + + "2. 노선 관리\n" + + "3. 구간 관리\n" + + "4. 지하철 노선도 출력\n" + + "Q. 종료"); + } + + public void printStations(final List inputs) { + for (String input : inputs) { + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + input); + } + } + + public void printStationManageView() { + System.out.println("## 역 관리 화면\n" + + "1. 역 등록\n" + + "2. 역 삭제\n" + + "3. 역 조회\n" + + "B. 돌아가기"); + } + + public void printLineManageView() { + System.out.println("## 노선 관리 화면\n" + + "1. 노선 등록\n" + + "2. 노선 삭제\n" + + "3. 노선 조회\n" + + "B. 돌아가기"); + } + + public void printSubwayAddSuccess() { + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + "지하철 노선이 등록되었습니다."); + } + + public void printSubwayDeleteSuccess() { + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + "지하철 노선이 삭제되었습니다."); + } + + public void printLines(final List inputs) { + for (String input : inputs) { + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + input); + } + } + + public void printSectionManageView() { + System.out.println("## 구간 관리 화면\n" + + "1. 구간 등록\n" + + "2. 구간 삭제\n" + + "B. 돌아가기"); + } + + public void printSubway(final Subway subway) { + for (Entry> entry : subway.getSubway().entrySet()) { + printLines(entry); + printStations(entry); + } + } + + private void printLines(final Entry> entry) { + final Line line = entry.getKey(); + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + line.getName().toString()); + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + "---"); + } + + private void printStations(final Entry> entry) { + for (Station s : entry.getValue()) { + System.out.println(Processmessage.SUCCESS_PREFIX.toMessage() + s.getName().toString()); + } + System.out.println(); + } +} From 2af22bc732395950c51e95fc689a6842d731e95b Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 10 May 2024 11:53:24 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=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/docs/README.md | 42 +++++++++---------- src/main/java/subway/domain/Line.java | 12 +++++- src/main/java/subway/domain/Station.java | 19 +++++++++ src/main/java/subway/domain/Subway.java | 4 ++ .../java/subway/service/SubwayService.java | 6 ++- 5 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/main/java/docs/README.md b/src/main/java/docs/README.md index 9d16f8177..b98faba7f 100644 --- a/src/main/java/docs/README.md +++ b/src/main/java/docs/README.md @@ -4,30 +4,30 @@ ### 지하철(Staion) -- [ ] 지하철역 등록 기능 - - [ ] [ERROR] 지하철역은 두글자 이상이여야 한다. - - [ ] [ERROR] 지하철역은 한국어만 가능합니다. - - [ ] [ERROR] 중복된 역 이름은 등록할 수 없습니다. -- [ ] 지하철역 삭제 기능 - - [ ] [ERROR] 존재하는 지하철역만 삭제 가능합니다. - - [ ] [ERROR] 노선에 등록된 역은 삭제가 안됩니다. -- [ ] 지하철역 전체 조회 기능 +- [x] 지하철역 등록 기능 + - [x] [ERROR] 지하철역은 두글자 이상이여야 한다. + - [x] [ERROR] 지하철역은 한국어만 가능합니다. + - [x] [ERROR] 중복된 역 이름은 등록할 수 없습니다. +- [x] 지하철역 삭제 기능 + - [x] [ERROR] 존재하는 지하철역만 삭제 가능합니다. + - [x] [ERROR] 노선에 등록된 역은 삭제가 안됩니다. +- [x] 지하철역 전체 조회 기능 ### 노선(Line) -- [ ] 노선 등록 기능 - - [ ] 등록시 상행 종점과 하행 종점을 입력받는다. - - [ ] [ERROR] 노선의 이름은 두글자 이상이여야 한다. -- [ ] 노선 삭제 기능 - - [ ] [ERROR] 존재하는 노선만 삭제 가능합니다. -- [ ] 노선 목록 조회 기능 -- [ ] 노선에 등록된 역 조회 기능 - - [ ] 노선의 상행 종점부터 하행 종점까지 순서대로 목록을 조회한다. +- [x] 노선 등록 기능 + - [x] 등록시 상행 종점과 하행 종점을 입력받는다. + - [x] [ERROR] 노선의 이름은 두글자 이상이여야 한다. +- [x] 노선 삭제 기능 + - [x] [ERROR] 존재하는 노선만 삭제 가능합니다. +- [x] 노선 목록 조회 기능 +- [x] 노선에 등록된 역 조회 기능 + - [x] 노선의 상행 종점부터 하행 종점까지 순서대로 목록을 조회한다. ### 구간 -- [ ] 존재하는 노선에 역을 추가한다. - - [ ] [ERROR] 등록된 역만 노선에 추가가 가능하다. -- [ ] 노선에 역을 삭제한다. - - [ ] [ERROR] 노선에 역이 2개 이하면 삭제할 수 없다. - - [ ] [ERROR] 노선에 존재하는 욕만 삭제할 수 있다. \ No newline at end of file +- [x] 존재하는 노선에 역을 추가한다. + - [x] [ERROR] 등록된 역만 노선에 추가가 가능하다. +- [x] 노선에 역을 삭제한다. + - [x] [ERROR] 노선에 역이 2개 이하면 삭제할 수 없다. + - [x] [ERROR] 노선에 존재하는 역만 삭제할 수 있다. \ No newline at end of file diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index 523ba685e..82cded2b9 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -1,14 +1,24 @@ package subway.domain; import java.util.Objects; +import subway.constant.message.ErrorMessage; public class Line { + + private static final int MIN_NAME_LENGTH = 2; private String name; - public Line(String name) { + public Line(final String name) { + validateNameLenght(name); this.name = name; } + private void validateNameLenght(final String input) { + if (input.length() < MIN_NAME_LENGTH) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "이름은 2글자 이상이여야 합니다."); + } + } + public String getName() { return name; } diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index 34d5a666a..aea99d8b9 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -1,11 +1,18 @@ package subway.domain; import java.util.Objects; +import java.util.regex.Pattern; +import subway.constant.message.ErrorMessage; public class Station { + + private final Pattern NAME_PATTERN = Pattern.compile("^[가-힣]+$"); + private static final int MIN_NAME_LENGTH = 2; private String name; public Station(final String name) { + validateNameLenght(name); + validateNameRegex(name); this.name = name; } @@ -13,6 +20,18 @@ public String getName() { return name; } + private void validateNameLenght(final String input) { + if (input.length() < MIN_NAME_LENGTH) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "이름은 2글자 이상이여야 합니다."); + } + } + + private void validateNameRegex(final String input) { + if (!NAME_PATTERN.matcher(input).matches()) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "한글만 입력 가능합니다."); + } + } + public boolean isEqualsByName(final String input) { return Objects.equals(name, input); } diff --git a/src/main/java/subway/domain/Subway.java b/src/main/java/subway/domain/Subway.java index a0e6d4009..b0e3dd726 100644 --- a/src/main/java/subway/domain/Subway.java +++ b/src/main/java/subway/domain/Subway.java @@ -31,6 +31,10 @@ public void addStationByLine(final Line line, final Station station, final int s throw new IllegalArgumentException("중복된 값을 저장할 수 없습니다."); } stations.add(stationIndex + INDEX_ADDER, station); + } + public int getStationSize(final Line line) { + List stations = subway.get(line); + return stations.size(); } } diff --git a/src/main/java/subway/service/SubwayService.java b/src/main/java/subway/service/SubwayService.java index 6023c9f4c..4b19c96d3 100644 --- a/src/main/java/subway/service/SubwayService.java +++ b/src/main/java/subway/service/SubwayService.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import subway.constant.message.ErrorMessage; import subway.domain.Line; import subway.domain.LineRepository; import subway.domain.Station; @@ -12,7 +13,7 @@ public class SubwayService { - + private static final int LIMIT_SUBWAY_STATION_SIZE = 2; private final Subway subway = new Subway(); private final LineRepository lineRepository = new LineRepository(); private final StationRepository stationRepository = new StationRepository(); @@ -95,6 +96,9 @@ public void addSubwayStation(final String inputLine, final String inputStation, public void deleteSubwayLine(final String inputLine) { final Line line = lineRepository.getByName(inputLine); + if (subway.getStationSize(line) <= LIMIT_SUBWAY_STATION_SIZE) { + throw new IllegalStateException(ErrorMessage.ERROR_PREFIX.toMessage() + "역이 2개 이하면 삭제할 수 없습니다."); + } subway.deleteSubwayByLine(line); } From ec9daf51f607359d4b4f74d27ad0cae36d6d762d Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 10 May 2024 16:42:14 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A6=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=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/Line.java | 10 +++++++++- src/main/java/subway/domain/LineRepository.java | 8 ++++---- src/main/java/subway/domain/Station.java | 14 +++++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java index 82cded2b9..2a808c4aa 100644 --- a/src/main/java/subway/domain/Line.java +++ b/src/main/java/subway/domain/Line.java @@ -6,13 +6,21 @@ public class Line { private static final int MIN_NAME_LENGTH = 2; - private String name; + private static final String NAME_SUFFIX = "선"; + private final String name; public Line(final String name) { + validateNameSuffix(name); validateNameLenght(name); this.name = name; } + private void validateNameSuffix(final String input) { + if (!input.endsWith(NAME_SUFFIX)) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "노선은 선으로 끝나야 합니다"); + } + } + private void validateNameLenght(final String input) { if (input.length() < MIN_NAME_LENGTH) { throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "이름은 2글자 이상이여야 합니다."); diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 5680977b7..b21e9402c 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -14,7 +14,7 @@ public List getAll() { public void save(final Line line) { if (lines.stream() - .anyMatch(element -> element.equals(line))) { + .anyMatch(element -> element.equals(line))) { throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "중복된 호선은 입력될 수 없습니다."); } lines.add(line); @@ -32,8 +32,8 @@ private boolean deleteLine(final String name) { public Line getByName(final String name) { return lines.stream() - .filter(e -> e.isEqualsByName(name)) - .findFirst() - .orElseThrow(() -> new IllegalStateException("이름에 해당하는 노선이 없습니다.")); + .filter(e -> e.isEqualsByName(name)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("이름에 해당하는 노선이 없습니다.")); } } diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java index aea99d8b9..c9f6d8ffe 100644 --- a/src/main/java/subway/domain/Station.java +++ b/src/main/java/subway/domain/Station.java @@ -7,11 +7,13 @@ public class Station { private final Pattern NAME_PATTERN = Pattern.compile("^[가-힣]+$"); + private static final String NAME_SUFFIX = "역"; private static final int MIN_NAME_LENGTH = 2; - private String name; + private final String name; public Station(final String name) { - validateNameLenght(name); + validateNameLength(name); + validateNameSuffix(name); validateNameRegex(name); this.name = name; } @@ -20,7 +22,13 @@ public String getName() { return name; } - private void validateNameLenght(final String input) { + private void validateNameSuffix(final String input) { + if (!input.endsWith(NAME_SUFFIX)) { + throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "지하철역은 역으로 끝나야 합니다"); + } + } + + private void validateNameLength(final String input) { if (input.length() < MIN_NAME_LENGTH) { throw new IllegalArgumentException(ErrorMessage.ERROR_PREFIX.toMessage() + "이름은 2글자 이상이여야 합니다."); } From 1d47e9cb765870b2b4ac94f7fcecb247cc6739ac Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 10 May 2024 17:06:06 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20DI=EB=A1=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=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/common/AppConfig.java | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/main/java/subway/common/AppConfig.java diff --git a/src/main/java/subway/common/AppConfig.java b/src/main/java/subway/common/AppConfig.java new file mode 100644 index 000000000..a951b83da --- /dev/null +++ b/src/main/java/subway/common/AppConfig.java @@ -0,0 +1,2 @@ +package subway.common;public class AppConfig { +} From 7bc488ed69bddc013e96e2c5e8242ad2f9685f0b Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 10 May 2024 17:06:49 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20DI=EB=A1=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=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/Application.java | 6 +-- src/main/java/subway/common/AppConfig.java | 51 ++++++++++++++++++- .../subway/controller/SubwayController.java | 17 +++++-- .../java/subway/service/SubwayService.java | 16 ++++-- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index fb77e68cc..0b5e6cdba 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,10 @@ package subway; -import subway.controller.SubwayController; +import subway.common.AppConfig; public class Application { public static void main(String[] args) { - final SubwayController subwayController = new SubwayController(); - subwayController.start(); + + AppConfig.getInstance().subwayController().start(); } } diff --git a/src/main/java/subway/common/AppConfig.java b/src/main/java/subway/common/AppConfig.java index a951b83da..505ff4838 100644 --- a/src/main/java/subway/common/AppConfig.java +++ b/src/main/java/subway/common/AppConfig.java @@ -1,2 +1,51 @@ -package subway.common;public class AppConfig { +package subway.common; + +import subway.controller.SubwayController; +import subway.domain.LineRepository; +import subway.domain.StationRepository; +import subway.domain.Subway; +import subway.service.SubwayService; +import subway.view.InputView; +import subway.view.OutputView; + +public class AppConfig { + + private static AppConfig instance; + + private AppConfig() { + } + + public static AppConfig getInstance() { + if (instance == null) { + instance = new AppConfig(); + } + return instance; + } + + public SubwayController subwayController() { + return new SubwayController(outputView(), inputView(), subwayService()); + } + + private OutputView outputView() { + return new OutputView(); + } + private InputView inputView() { + return new InputView(); + } + + private SubwayService subwayService() { + return new SubwayService(subway(), lineRepository(), stationRepository()); + } + + private Subway subway() { + return new Subway(); + } + + private LineRepository lineRepository() { + return new LineRepository(); + } + + private StationRepository stationRepository() { + return new StationRepository(); + } } diff --git a/src/main/java/subway/controller/SubwayController.java b/src/main/java/subway/controller/SubwayController.java index 1e3460d7f..e5fa44881 100644 --- a/src/main/java/subway/controller/SubwayController.java +++ b/src/main/java/subway/controller/SubwayController.java @@ -13,9 +13,20 @@ public class SubwayController { - private final OutputView outputView = new OutputView(); - private final InputView inputView = new InputView(); - private final SubwayService subwayService = new SubwayService(); + private final OutputView outputView; + private final InputView inputView; + + public SubwayController( + final OutputView outputView, + final InputView inputView, + final SubwayService subwayService + ) { + this.outputView = outputView; + this.inputView = inputView; + this.subwayService = subwayService; + } + + private final SubwayService subwayService; public void start() { subwayService.initializeSubway(); diff --git a/src/main/java/subway/service/SubwayService.java b/src/main/java/subway/service/SubwayService.java index 4b19c96d3..518c58172 100644 --- a/src/main/java/subway/service/SubwayService.java +++ b/src/main/java/subway/service/SubwayService.java @@ -14,9 +14,19 @@ public class SubwayService { private static final int LIMIT_SUBWAY_STATION_SIZE = 2; - private final Subway subway = new Subway(); - private final LineRepository lineRepository = new LineRepository(); - private final StationRepository stationRepository = new StationRepository(); + private final Subway subway; + private final LineRepository lineRepository; + private final StationRepository stationRepository; + + public SubwayService( + final Subway subway, + final LineRepository lineRepository, + final StationRepository stationRepository + ) { + this.subway = subway; + this.lineRepository = lineRepository; + this.stationRepository = stationRepository; + } public void saveStation(final String input) { final Station station = new Station(input); From 8f0d81f7c2ee1094c0620fdbdf92d96990f6359a Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Fri, 10 May 2024 23:57:30 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=88=EC=9E=90=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 --- .../common/{ExceptionHander.java => ExceptionHandler.java} | 2 +- src/main/java/subway/controller/SubwayController.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/subway/common/{ExceptionHander.java => ExceptionHandler.java} (90%) diff --git a/src/main/java/subway/common/ExceptionHander.java b/src/main/java/subway/common/ExceptionHandler.java similarity index 90% rename from src/main/java/subway/common/ExceptionHander.java rename to src/main/java/subway/common/ExceptionHandler.java index bf8d73e9f..b22d66718 100644 --- a/src/main/java/subway/common/ExceptionHander.java +++ b/src/main/java/subway/common/ExceptionHandler.java @@ -1,6 +1,6 @@ package subway.common; -public class ExceptionHander { +public class ExceptionHandler { public static void retryOnException(final Runnable runnable) { try { diff --git a/src/main/java/subway/controller/SubwayController.java b/src/main/java/subway/controller/SubwayController.java index e5fa44881..2bd1747cc 100644 --- a/src/main/java/subway/controller/SubwayController.java +++ b/src/main/java/subway/controller/SubwayController.java @@ -1,7 +1,7 @@ package subway.controller; import java.util.List; -import subway.common.ExceptionHander; +import subway.common.ExceptionHandler; import subway.constant.LineCommand; import subway.constant.MainCommand; import subway.constant.SectionCommand; @@ -30,7 +30,7 @@ public SubwayController( public void start() { subwayService.initializeSubway(); - ExceptionHander.retryOnException(this::startSubway); + ExceptionHandler.retryOnException(this::startSubway); } private void startSubway() { From 7de2dd0e5d35b65b1d3c061ca6812a97ad530211 Mon Sep 17 00:00:00 2001 From: Jung Yunho Date: Sat, 11 May 2024 05:16:35 +0900 Subject: [PATCH 8/8] =?UTF-8?q?test:=20domain=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=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 --- .../java/subway/constant/CommandTest.java | 123 ++++++++++++++++++ .../subway/domain/LineRepositoryTest.java | 120 +++++++++++++++++ src/test/java/subway/domain/LineTest.java | 49 +++++++ .../subway/domain/StationRepositoryTest.java | 120 +++++++++++++++++ src/test/java/subway/domain/StationTest.java | 60 +++++++++ 5 files changed, 472 insertions(+) create mode 100644 src/test/java/subway/constant/CommandTest.java create mode 100644 src/test/java/subway/domain/LineRepositoryTest.java create mode 100644 src/test/java/subway/domain/LineTest.java create mode 100644 src/test/java/subway/domain/StationRepositoryTest.java create mode 100644 src/test/java/subway/domain/StationTest.java diff --git a/src/test/java/subway/constant/CommandTest.java b/src/test/java/subway/constant/CommandTest.java new file mode 100644 index 000000000..b4e492fde --- /dev/null +++ b/src/test/java/subway/constant/CommandTest.java @@ -0,0 +1,123 @@ +package subway.constant; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.ThrowingSupplier; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@SuppressWarnings("NonAsciiCharacters") +class CommandTest { + + @Nested + class 메인 { + + @ParameterizedTest + @ValueSource(strings = {"1", "2", "3", "4", "Q"}) + void 존재하는_버튼만_눌러야한다(String input) { + //given + //when + final ThrowingSupplier supplier = () -> MainCommand.from(input); + + //then + assertDoesNotThrow(supplier); + } + + @Test + void 존재하는_버튼을_입력하면_정상_생성한다() { + //given + final var input = "B"; + + //when + final ThrowingCallable throwingCallable = () -> MainCommand.from(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + } + + @Nested + class 노선 { + + @ParameterizedTest + @ValueSource(strings = {"1", "2", "3", "B"}) + void 존재하는_버튼만_눌러야한다(String input) { + //given + //when + final ThrowingSupplier supplier = () -> LineCommand.from(input); + + //then + assertDoesNotThrow(supplier); + } + + @Test + void 존재하는_버튼을_입력하면_정상_생성한다() { + //given + final var input = "A"; + + //when + final ThrowingCallable throwingCallable = () -> LineCommand.from(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + } + + @Nested + class 지하철역 { + + @ParameterizedTest + @ValueSource(strings = {"1", "2", "3", "B"}) + void 존재하는_버튼만_눌러야한다(String input) { + //given + //when + final ThrowingSupplier supplier = () -> StationCommand.from(input); + + //then + assertDoesNotThrow(supplier); + } + + @Test + void 존재하는_버튼을_입력하면_정상_생성한다() { + //given + final var input = "A"; + + //when + final ThrowingCallable throwingCallable = () -> StationCommand.from(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + } + + @Nested + class 구간 { + + @ParameterizedTest + @ValueSource(strings = {"1", "2", "B"}) + void 존재하는_버튼만_눌러야한다(String input) { + //given + //when + final ThrowingSupplier supplier = () -> SectionCommand.from(input); + + //then + assertDoesNotThrow(supplier); + } + + @Test + void 존재하는_버튼을_입력하면_정상_생성한다() { + //given + final var input = "Q"; + + //when + final ThrowingCallable throwingCallable = () -> SectionCommand.from(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/LineRepositoryTest.java b/src/test/java/subway/domain/LineRepositoryTest.java new file mode 100644 index 000000000..e0f32a83d --- /dev/null +++ b/src/test/java/subway/domain/LineRepositoryTest.java @@ -0,0 +1,120 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +@SuppressWarnings("NonAsciiCharacters") +class LineRepositoryTest { + + private LineRepository lineRepository; + + @BeforeEach + void 테스트용_객체_주입() { + lineRepository = new LineRepository(); + + lineRepository.save(new Line("1호선")); + lineRepository.save(new Line("2호선")); + lineRepository.save(new Line("3호선")); + } + + @Test + void 노선의_모든_객체를_반환한다() { + //given + //when + final var lists = lineRepository.getAll(); + + //then + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(lists).hasSize(3); + softly.assertThat(lists.get(0)).isEqualTo(new Line("1호선")); + softly.assertThat(lists.get(1)).isEqualTo(new Line("2호선")); + softly.assertThat(lists.get(2)).isEqualTo(new Line("3호선")); + }); + } + + @Test + void 다른_이름의_노선을_저장해야한다() { + //given + final var line = new Line("1호선"); + + //when + final ThrowingCallable throwingCallable = () -> lineRepository.save(line); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 노선을_정상적으로_저장한다() { + //given + final var line = new Line("4호선"); + + //when + lineRepository.save(line); + + //then + final var lists = lineRepository.getAll(); + + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(lists).hasSize(4); + softly.assertThat(lists.get(3)).isEqualTo(new Line("4호선")); + }); + } + + @Test + void 존재하는_노선을_삭제해야한다() { + //given + final var lineName = "5호선"; + + //when + final ThrowingCallable throwingCallable = () -> lineRepository.delete(lineName); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 노선을_삭제한다() { + //given + final var lineName = "1호선"; + + //when + lineRepository.delete(lineName); + + //then + final var lines = lineRepository.getAll(); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(lines).hasSize(2); + softly.assertThat(lines).isNotIn(new Line(lineName)); + }); + } + + @Test + void 존재하는_이름으로_노선을_가져와야한다() { + //given + final var lineName = "5호선"; + + //when + final ThrowingCallable throwingCallable = () -> lineRepository.getByName(lineName); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalStateException.class); + } + + @Test + void 이름으로_노선을_가져온다() { + //given + final var lineName = "1호선"; + + //when + final var line = lineRepository.getByName(lineName); + + //then + assertThat(line).isEqualTo(new Line(lineName)); + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/LineTest.java b/src/test/java/subway/domain/LineTest.java new file mode 100644 index 000000000..e1ce1a974 --- /dev/null +++ b/src/test/java/subway/domain/LineTest.java @@ -0,0 +1,49 @@ +package subway.domain; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.Test; + +@SuppressWarnings("NonAsciiCharacters") +class LineTest { + + @Test + void 이름의_길이는_2보다_커야한다() { + //given + final var name = "선"; + + //when + final ThrowingCallable throwingCallable = () -> new Line(name); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 이름은_선으로_끝나야_합니다() { + //given + final var name = "5호선"; + + //when + final ThrowingCallable throwingCallable = () -> new Line(name); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 이름이_일치하는지_확인합니다() { + //given + final var lineName = "2호선"; + final var actualLine = new Line(lineName); + + //when + //then + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(actualLine.isEqualsByName(lineName)).isTrue(); + softly.assertThat(actualLine.isEqualsByName("9호선")).isFalse(); + }); + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/StationRepositoryTest.java b/src/test/java/subway/domain/StationRepositoryTest.java new file mode 100644 index 000000000..1ae693c7c --- /dev/null +++ b/src/test/java/subway/domain/StationRepositoryTest.java @@ -0,0 +1,120 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import org.assertj.core.api.SoftAssertions; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +@SuppressWarnings("NonAsciiCharacters") +class StationRepositoryTest { + + private StationRepository stationRepository; + + @BeforeEach + void 테스트용_객체_주입() { + stationRepository = new StationRepository(); + + stationRepository.save(new Station("인덕원역")); + stationRepository.save(new Station("평촌역")); + stationRepository.save(new Station("범계역")); + } + + @Test + void 역의_모든_객체를_반환한다() { + //given + //when + final var stations = stationRepository.getAll(); + + //then + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(stations).hasSize(3); + softly.assertThat(stations.get(0)).isEqualTo(new Station("인덕원역")); + softly.assertThat(stations.get(1)).isEqualTo(new Station("평촌역")); + softly.assertThat(stations.get(2)).isEqualTo(new Station("범계역")); + }); + } + + @Test + void 다른_이름의_역을_저장해야한다() { + //given + final var station = new Station("인덕원역"); + + //when + final ThrowingCallable throwingCallable = () -> stationRepository.save(station); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 역을_정상적으로_저장한다() { + //given + final var station = new Station("과천역"); + + //when + stationRepository.save(station); + + //then + final var lists = stationRepository.getAll(); + + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(lists).hasSize(4); + softly.assertThat(lists.get(3)).isEqualTo(new Station("과천역")); + }); + } + + @Test + void 존재하는_역을_삭제해야한다() { + //given + final var stationName = "과천역"; + + //when + final ThrowingCallable throwingCallable = () -> stationRepository.delete(stationName); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalStateException.class); + } + + @Test + void 역을_삭제한다() { + //given + final var stationName = "인덕원역"; + + //when + stationRepository.delete(stationName); + + //then + final var stations = stationRepository.getAll(); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(stations).hasSize(2); + softly.assertThat(stations).isNotIn(new Station(stationName)); + }); + } + + @Test + void 존재하는_이름으로_역을_가져와야한다() { + //given + final var stationName = "과천역"; + + //when + final ThrowingCallable throwingCallable = () -> stationRepository.getByName(stationName); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalStateException.class); + } + + @Test + void 이름으로_역을_가져온다() { + //given + final var stationName = "인덕원역"; + + //when + final var station = stationRepository.getByName(stationName); + + //then + assertThat(station).isEqualTo(new Station(stationName)); + } +} \ No newline at end of file diff --git a/src/test/java/subway/domain/StationTest.java b/src/test/java/subway/domain/StationTest.java new file mode 100644 index 000000000..b0d1ebff2 --- /dev/null +++ b/src/test/java/subway/domain/StationTest.java @@ -0,0 +1,60 @@ +package subway.domain; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.ThrowingSupplier; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@SuppressWarnings("NonAsciiCharacters") +class StationTest { + + @Test + void 이름의_길이는_2보다_커야한다() { + //given + final var name = "역"; + + //when + final ThrowingCallable throwingCallable = () -> new Station(name); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @ValueSource(strings = {"asdf", "asd역"}) + void 지하철역_이름은_한글만_가능합니다(String input) { + //given + //when + final ThrowingCallable throwingCallable = () -> new Station(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @ValueSource(strings = {"인덕원", "과천정부청사"}) + void 지하철역_이름은_역으로_끝나야합니다(String input) { + //given + //when + final ThrowingCallable throwingCallable = () -> new Station(input); + + //then + assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 이름을_정상적으로_입력하면_생성한다() { + //given + final var name = "인덕원역"; + + //when + final ThrowingSupplier supplier = () -> new Station(name); + + //then + assertDoesNotThrow(supplier); + } +} \ No newline at end of file