diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..af1355171 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,88 @@ +## 기능 목록 + +### 초기 설정 +- [x] 사전 등록 정보 초기 설정 + +### 메인 화면 +- [x] 메인 화면 출력 +- [x] 원하는 기능 입력 + - [x] 존재하지 않는 기능을 입력한 경우 예외 발생 + +### 역 관리 +- [x] 역 관리 화면 출력 +- [x] 원하는 기능 입력 + +**역 등록** +- [x] 등록할 역 이름 입력 + - [x] 중복된 이름의 역이 있을 경우 예외 발생 + - [x] 역 이름이 2글자 이상이 아닐 경우 예외 발생 +- [x] 등록 +- [x] 등록 완료 안내 출력 + +**역 삭제** +- [x] 삭제할 역 이름 입력 + - [x] 존재하지 않는 역일 경우 예외 발생 +- [x] 삭제 + - [x] 노선에 등록된 역일 경우 노선에서 삭제 + - [x] 역 삭제 +- [x] 삭제 완료 안내 출력 + +**역 조회** +- [x] 등록되어 있는 역 목록 출력 + +### 노선 관리 + +- [x] 노선 관리 화면 출력 +- [x] 원하는 기능 선택 + +**노선 등록** + +- [x] 등록할 노선 이름 입력 + - [x] 존재하는 노선일 경우 예외 발생 + - [x] 1글자 이하일 경우 예외 발생 +- [x] 상행 종점역 이름 입력 +- [x] 하행 종점역 이름 입력 + - [x] 존재하지 않는 역일 경우 예외 발생 + - [x] 상행 종점역과 하행 종점역이 같을 경우 예외 발생 +- [x] 노선 생성 +- [x] 노선 생성 완료 안내 출력 + +**노선 삭제** + +- [x] 삭제할 노선 이름 입력 + - [x] 존재하지 않는 노선일 경우 예외 발생 +- [x] 노선 삭제 +- [x] 삭제 완료 안내 출력 + +**노선 조회** +- [x] 노선 목록 출력 + +### 구간 관리 + +- [x] 구간 관리 화면 출력 +- [x] 원하는 기능 선택 + +**구간 등록** + +- [x] 노선 이름 입력 + - [x] 존재하지 않을 경우 예외 발생 +- [x] 역 이름 입력 + - [x] 존재하지 않을 경우 예외 발생 + - [x] 이미 구간에 존재하는 역일 경우 예외 발생 +- [x] 순서 입력 + - [x] 범위를 벗어날 경우 예외 발생 +- [x] 구간 등록 +- [x] 등록 완료 안내 출력 + +**구간 삭제** + +- [x] 삭제할 노선 입력 + - [x] 존재하지 않는 노선일 경우 예외 발생 +- [x] 삭제할 구간의 역 입력 + - [x] 구간에 존재하지 않는 역일 경우 예외 발생 +- [x] 구간 삭제 +- [x] 삭제 완료 안내 출력 + +### 지하철 노선도 출력 + +- [x] 지하철 노선도 출력 \ No newline at end of file diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java index 0bcf786cc..e3a924b50 100644 --- a/src/main/java/subway/Application.java +++ b/src/main/java/subway/Application.java @@ -1,10 +1,13 @@ package subway; +import subway.main.SubwayController; + import java.util.Scanner; public class Application { public static void main(String[] args) { final Scanner scanner = new Scanner(System.in); - // TODO: 프로그램 구현 + SubwayController controller = new SubwayController(scanner); + controller.start(); } } diff --git a/src/main/java/subway/constant/ExceptionMessage.java b/src/main/java/subway/constant/ExceptionMessage.java new file mode 100644 index 000000000..0919819f2 --- /dev/null +++ b/src/main/java/subway/constant/ExceptionMessage.java @@ -0,0 +1,27 @@ +package subway.constant; + +public enum ExceptionMessage { + + INVALID_OPTION("존재하지 않는 기능입니다."), + INVALID_LENGTH("2글자 이상 입력만 가능합니다."), + DUPLICATE_STATION("이미 존재하는 역입니다."), + NOT_EXISTENT_STATION("존재하지 않는 역입니다."), + DUPLICATE_LAST_STATION("상행 종점 역과 하행 종점역인 다른 역으로 입력되어야 합니다."), + DUPLICATE_LINE("이미 존재하는 노선입니다."), + NOT_EXISTENT_LINE("존재하지 않는 노선입니다."), + DUPLICATE_SECTION_STATION("해당 노선에 이미 존재하는 역입니다."), + NOT_EXISTING_STATION("해당 노선에 입력하신 역이 존재하지 않습니다."), + OUT_OF_RANGE("해당 순서에 역을 추가할 수 없습니다."); + + private static final String PREFIX = "[ERROR] "; + private final String message; + + ExceptionMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return PREFIX + message; + } +} diff --git a/src/main/java/subway/constant/InformationMessage.java b/src/main/java/subway/constant/InformationMessage.java new file mode 100644 index 000000000..18249489a --- /dev/null +++ b/src/main/java/subway/constant/InformationMessage.java @@ -0,0 +1,24 @@ +package subway.constant; + +public enum InformationMessage { + + COMPLETE_CREATE_STATION("지하철 역이 등록되었습니다."), + COMPLETE_DELETE_STATION("지하철 역이 삭제되었습니다."), + READ_ELEMENT("%s\n"), + CREATE_LINE("지하철 노선이 등록되었습니다."), + DELETE_LINE("지하철 노선이 삭제되었습니다."), + CREATE_SECTION("구간이 등록되었습니다."), + DELETE_SECTION("구간이 삭제되었습니다."); + + private static final String PREFIX = "[INFO] "; + private final String message; + + InformationMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return PREFIX + message; + } +} diff --git a/src/main/java/subway/constant/OutputMessage.java b/src/main/java/subway/constant/OutputMessage.java new file mode 100644 index 000000000..441418f79 --- /dev/null +++ b/src/main/java/subway/constant/OutputMessage.java @@ -0,0 +1,36 @@ +package subway.constant; + +public enum OutputMessage { + + MAIN_MESSAGE("메인 화면"), + OPTION_SELECT("원하는 기능을 선택하세요."), + STATION_OPTION_SELECT("역 관리 화면"), + CREATE_STATION("등록할 역 이름을 입력하세요."), + DELETE_STATION("삭제할 역 이름을 입력하세요."), + READ_STATION("역 목록"), + LINE_MANAGEMENT_SCREEN("노선 관리 화면"), + CREATE_LINE("등록할 노선 이름을 입력하세요."), + UP_BOUND_STATION("등록할 노선의 상행 종점역 이름을 입력하세요."), + DESCENDING_STATION("등록할 노선의 하행 종점역 이름을 입력하세요."), + DELETE_LINE("삭제할 노선 이름을 입력하세요."), + READ_LINE("노선 목록"), + SECTION_MANAGEMENT_SCREEN("구간 관리 화면"), + SECTION_LINE("노선을 입력하세요."), + SECTION_STATION("역이름을 입력하세요."), + SECTION_INDEX("순서를 입력하세요."), + DELETE_SECTION_LINE("삭제할 구간의 노선을 입력하세요."), + DELETE_SECTION_STATION("삭제할 구간의 역을 입력하세요."), + SUBWAY_MAP("지하철 노선도"); + + private static final String PREFIX = "## "; + private final String message; + + OutputMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return PREFIX + message; + } +} diff --git a/src/main/java/subway/constant/PrintElement.java b/src/main/java/subway/constant/PrintElement.java new file mode 100644 index 000000000..3ea351079 --- /dev/null +++ b/src/main/java/subway/constant/PrintElement.java @@ -0,0 +1,19 @@ +package subway.constant; + +public enum PrintElement { + + COMMA(". "), + NEW_LINE("\n"), + DOTTED_LINE("---"); + + private final String element; + + PrintElement(String element) { + this.element = element; + } + + @Override + public String toString() { + return element; + } +} diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java deleted file mode 100644 index f4d738d5a..000000000 --- a/src/main/java/subway/domain/Line.java +++ /dev/null @@ -1,15 +0,0 @@ -package subway.domain; - -public class Line { - private String name; - - public Line(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // 추가 기능 구현 -} diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java deleted file mode 100644 index 49132ddb6..000000000 --- a/src/main/java/subway/domain/LineRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package subway.domain; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class LineRepository { - private static final List lines = new ArrayList<>(); - - public static List lines() { - return Collections.unmodifiableList(lines); - } - - public static void addLine(Line line) { - lines.add(line); - } - - public static boolean deleteLineByName(String name) { - return lines.removeIf(line -> Objects.equals(line.getName(), name)); - } -} diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java deleted file mode 100644 index bdb142590..000000000 --- a/src/main/java/subway/domain/Station.java +++ /dev/null @@ -1,15 +0,0 @@ -package subway.domain; - -public class Station { - private String name; - - public Station(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - // 추가 기능 구현 -} diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java deleted file mode 100644 index b7245c0f3..000000000 --- a/src/main/java/subway/domain/StationRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package subway.domain; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class StationRepository { - private static final List stations = new ArrayList<>(); - - public static List stations() { - return Collections.unmodifiableList(stations); - } - - public static void addStation(Station station) { - stations.add(station); - } - - public static boolean deleteStation(String name) { - return stations.removeIf(station -> Objects.equals(station.getName(), name)); - } -} diff --git a/src/main/java/subway/line/Line.java b/src/main/java/subway/line/Line.java new file mode 100644 index 000000000..dea0cfead --- /dev/null +++ b/src/main/java/subway/line/Line.java @@ -0,0 +1,45 @@ +package subway.line; + +import subway.constant.InformationMessage; +import subway.constant.PrintElement; +import subway.station.Name; +import subway.station.Station; + +public class Line { + + private final Name name; + private final StopStations stopStations; + + public Line(Name name, StopStations stopStations) { + this.name = name; + this.stopStations = stopStations; + } + + public boolean isSame(Name name) { + return name.equals(this.name); + } + + public void addStopStation(Station station, int index) { + stopStations.addStation(station, index); + } + + public void deleteStopStation(Station station) { + stopStations.deleteStation(station); + } + + public boolean isContainStation(Station station) { + return stopStations.contain(station); + } + + @Override + public String toString() { + return String.format(InformationMessage.READ_ELEMENT.toString(), name); + } + + public String getSubwayMap() { + return String.valueOf(this) + + PrintElement.DOTTED_LINE + + PrintElement.NEW_LINE + + stopStations; + } +} diff --git a/src/main/java/subway/line/LineController.java b/src/main/java/subway/line/LineController.java new file mode 100644 index 000000000..552acba3d --- /dev/null +++ b/src/main/java/subway/line/LineController.java @@ -0,0 +1,98 @@ +package subway.line; + +import subway.station.Name; +import subway.station.Station; +import subway.view.line.LineInputView; +import subway.view.line.LineOutputView; + +import java.util.Scanner; + +public class LineController { + + private final LineInputView inputView; + private final LineOutputView outputView; + private final LineService lineService; + + public LineController(Scanner scanner) { + this.inputView = new LineInputView(scanner); + this.outputView = new LineOutputView(); + this.lineService = new LineService(); + } + + public void start() { + while (true) { + try { + LineOption option = readOption(); + if (option.isBack()) { + break; + } + createLine(option); + deleteLine(option); + printLines(option); + } catch (IllegalArgumentException exception) { + outputView.printExceptionMessage(exception.getMessage()); + } + } + } + + private LineOption readOption() { + outputView.printLineOption(); + outputView.printOptions(); + LineOption option = inputView.readOption(); + outputView.printNewLine(); + return option; + } + + public void createLine(LineOption option) { + if (option.isCreate()) { + Name name = readName(); + Station upBoundStation = readUpBoundStation(); + Station descendingStation = readDescendingStation(); + lineService.create(name, upBoundStation, descendingStation); + outputView.printCreateLine(); + outputView.printNewLine(); + } + } + + private Name readName() { + outputView.printReadLineName(); + Name name = inputView.readLineName(); + outputView.printNewLine(); + return name; + } + + private Station readUpBoundStation() { + outputView.printUpBoundStation(); + Station station = inputView.readUpBoundStation(); + outputView.printNewLine(); + return station; + } + + private Station readDescendingStation() { + outputView.printDescendingStation(); + Station station = inputView.readDescendingStation(); + outputView.printNewLine(); + return station; + } + + public void deleteLine(LineOption option) { + if (option.isDelete()) { + lineService.delete(readDeleteStation()); + outputView.printDeleteLine(); + outputView.printNewLine(); + } + } + + private Name readDeleteStation() { + outputView.printReadDeleteLine(); + Name name = inputView.readDeleteStation(); + outputView.printNewLine(); + return name; + } + + public void printLines(LineOption option) { + if (option.isRead()) { + outputView.printLines(); + } + } +} diff --git a/src/main/java/subway/line/LineOption.java b/src/main/java/subway/line/LineOption.java new file mode 100644 index 000000000..adfa1753f --- /dev/null +++ b/src/main/java/subway/line/LineOption.java @@ -0,0 +1,52 @@ +package subway.line; + +import subway.constant.ExceptionMessage; + +import java.util.Arrays; + +public enum LineOption { + + CREATE("1", "노선 등록"), + DELETE("2", "노선 삭제"), + READ("3", "노선 조회"), + BACK("B", "돌아가기"); + + private final String option; + private final String title; + + LineOption(String option, String title) { + this.option = option; + this.title = title; + } + + public static LineOption getOption(String option) { + return Arrays.stream(LineOption.values()) + .filter(value -> option.equals(value.option)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.INVALID_OPTION.toString())); + } + + public boolean isCreate() { + return this == CREATE; + } + + public boolean isDelete() { + return this == DELETE; + } + + public boolean isRead() { + return this == READ; + } + + public boolean isBack() { + return this == BACK; + } + + public String getOption() { + return option; + } + + public String getTitle() { + return title; + } +} diff --git a/src/main/java/subway/line/LineRepository.java b/src/main/java/subway/line/LineRepository.java new file mode 100644 index 000000000..c3edc7d26 --- /dev/null +++ b/src/main/java/subway/line/LineRepository.java @@ -0,0 +1,61 @@ +package subway.line; + +import subway.constant.ExceptionMessage; +import subway.station.Name; +import subway.station.Station; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class LineRepository { + private static final List lines = new ArrayList<>(); + + public static List lines() { + return Collections.unmodifiableList(lines); + } + + public static void addLine(Name name, StopStations stations) { + validateStation(name); + lines.add(new Line(name, stations)); + } + + private static void validateStation(Name name) { + if (isDuplicateName(name)) { + throw new IllegalArgumentException(ExceptionMessage.DUPLICATE_LINE.toString()); + } + } + + private static boolean isDuplicateName(Name name) { + return lines.stream() + .anyMatch(line -> line.isSame(name)); + } + + public static void deleteStopStation(Station station) { + lines.stream() + .filter(line -> line.isContainStation(station)) + .forEach(lines -> lines.deleteStopStation(station)); + } + + public static void deleteLineByName(Name name) { + Line line = findLineByName(name); + lines.remove(line); + } + + public static void addStopStation(Name lineName, Station station, int index) { + Line line = findLineByName(lineName); + line.addStopStation(station, index); + } + + public static void deleteStopStation(Name lineName, Station station) { + Line line = findLineByName(lineName); + line.deleteStopStation(station); + } + + public static Line findLineByName(Name name) { + return lines.stream() + .filter(line -> line.isSame(name)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.NOT_EXISTENT_LINE.toString())); + } +} diff --git a/src/main/java/subway/line/LineService.java b/src/main/java/subway/line/LineService.java new file mode 100644 index 000000000..039f541b5 --- /dev/null +++ b/src/main/java/subway/line/LineService.java @@ -0,0 +1,17 @@ +package subway.line; + +import subway.station.Name; +import subway.station.Station; + +import java.util.List; + +public class LineService { + + public void create(Name name, Station upBoundStation, Station descendingStation) { + LineRepository.addLine(name, new StopStations(List.of(upBoundStation, descendingStation))); + } + + public void delete(Name name) { + LineRepository.deleteLineByName(name); + } +} \ No newline at end of file diff --git a/src/main/java/subway/line/StopStations.java b/src/main/java/subway/line/StopStations.java new file mode 100644 index 000000000..d0299bf75 --- /dev/null +++ b/src/main/java/subway/line/StopStations.java @@ -0,0 +1,72 @@ +package subway.line; + +import subway.constant.ExceptionMessage; +import subway.station.Station; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class StopStations { + + private static final int START_INDEX = 1; + + private final List element; + + public StopStations(List stations) { + validateDuplicate(stations); + this.element = new ArrayList<>(stations); + } + + private void validateDuplicate(List stations) { + Set checkStation = new HashSet<>(stations); + if (checkStation.size() != stations.size()) { + throw new IllegalArgumentException(ExceptionMessage.DUPLICATE_LAST_STATION.toString()); + } + } + + public void addStation(Station station, int index) { + validateStation(station, index); + element.add(index - START_INDEX, station); + } + + private void validateStation(Station station , int index) { + validateDuplicateStation(station); + validateRange(index); + } + + private void validateDuplicateStation(Station station) { + if (element.contains(station)) { + throw new IllegalArgumentException(ExceptionMessage.DUPLICATE_SECTION_STATION.toString()); + } + } + + private void validateRange(int index) { + if (!(1 <= index && index <= element.size())) { + throw new IllegalArgumentException(ExceptionMessage.OUT_OF_RANGE.toString()); + } + } + + public void deleteStation(Station station) { + validateExistingStation(station); + element.remove(station); + } + + private void validateExistingStation(Station station) { + if (!element.contains(station)) { + throw new IllegalArgumentException(ExceptionMessage.NOT_EXISTING_STATION.toString()); + } + } + + public boolean contain(Station station) { + return element.contains(station); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + element.forEach(stringBuilder::append); + return stringBuilder.toString(); + } +} diff --git a/src/main/java/subway/main/Initialization.java b/src/main/java/subway/main/Initialization.java new file mode 100644 index 000000000..e182382a0 --- /dev/null +++ b/src/main/java/subway/main/Initialization.java @@ -0,0 +1,57 @@ +package subway.main; + +import subway.line.LineRepository; +import subway.line.StopStations; +import subway.station.Name; +import subway.station.Station; +import subway.station.StationRepository; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Initialization { + + private static final String STATIONS = "교대역, 강남역, 역삼역, 남부터미널역, 양재역, 양재시민의숲역, 매봉역"; + private static final String LINE_TWO = "2호선"; + private static final String LINE_TWO_STATIONS = "교대역, 강남역, 역삼역"; + private static final String LINE_THREE = "3호선"; + private static final String LINE_THREE_STATIONS = "교대역, 남부터미널역, 양재역, 매봉역"; + private static final String LINE_DX = "신분당선"; + private static final String LINE_DX_STATIONS = "강남역, 양재역, 양재시민의숲역"; + + private static final String REGEX = ", "; + + public static void init() { + initStation(); + initLineTwo(); + initLineThree(); + initLineDX(); + } + + private static void initStation() { + Arrays.stream(STATIONS.split(REGEX)) + .forEach(name -> StationRepository.addStation(new Name(name))); + } + + private static void initLineTwo() { + List stopStation = Arrays.stream(LINE_TWO_STATIONS.split(REGEX)) + .map(name -> StationRepository.findByName(new Name(name))) + .collect(Collectors.toList()); + LineRepository.addLine(new Name(LINE_TWO), new StopStations(stopStation)); + } + + private static void initLineThree() { + List stopStation = Arrays.stream(LINE_THREE_STATIONS.split(REGEX)) + .map(name -> StationRepository.findByName(new Name(name))) + .collect(Collectors.toList()); + LineRepository.addLine(new Name(LINE_THREE), new StopStations(stopStation)); + } + + private static void initLineDX() { + List stopStation = Arrays.stream(LINE_DX_STATIONS.split(REGEX)) + .map(name -> StationRepository.findByName(new Name(name))) + .collect(Collectors.toList()); + LineRepository.addLine(new Name(LINE_DX), new StopStations(stopStation)); + } +} diff --git a/src/main/java/subway/main/MainOption.java b/src/main/java/subway/main/MainOption.java new file mode 100644 index 000000000..112fafa02 --- /dev/null +++ b/src/main/java/subway/main/MainOption.java @@ -0,0 +1,57 @@ +package subway.main; + +import subway.constant.ExceptionMessage; + +import java.util.Arrays; + +public enum MainOption { + STATION_MANAGEMENT("1", "역 관리"), + LINE_MANAGEMENT("2", "노선 관리"), + SECTION_MANAGEMENT("3", "구간 관리"), + SUBWAY_MAP("4", "지하철 노선도 출력"), + QUIT("Q", "종료"); + + + private final String option; + private final String title; + + MainOption(String option, String title) { + this.option = option; + this.title = title; + } + + public static MainOption getMainOption(String option) { + return Arrays.stream(MainOption.values()) + .filter(value -> option.equals(value.option)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.INVALID_OPTION.toString())); + } + + public boolean isStationManagement() { + return this == STATION_MANAGEMENT; + } + + public boolean isLineManagement() { + return this == LINE_MANAGEMENT; + } + + public boolean isSectionManagement() { + return this == SECTION_MANAGEMENT; + } + + public boolean isSubwayMap() { + return this == SUBWAY_MAP; + } + + public boolean isQuit() { + return this == MainOption.QUIT; + } + + public String getOption() { + return option; + } + + public String getTitle() { + return title; + } +} diff --git a/src/main/java/subway/main/SubwayController.java b/src/main/java/subway/main/SubwayController.java new file mode 100644 index 000000000..5b42e1ed2 --- /dev/null +++ b/src/main/java/subway/main/SubwayController.java @@ -0,0 +1,83 @@ +package subway.main; + +import subway.line.LineController; +import subway.section.SectionController; +import subway.station.StationController; +import subway.subwaymap.SubwayMapController; +import subway.view.InputView; +import subway.view.OutputView; + +import java.util.Scanner; + +public class SubwayController { + + private final OutputView outputView; + private final InputView inputView; + private final StationController stationController; + private final LineController lineController; + private final SectionController sectionController; + private final SubwayMapController subwayMapController; + + public SubwayController(Scanner scanner) { + this.outputView = new OutputView(); + this.inputView = new InputView(scanner); + this.stationController = new StationController(scanner); + this.lineController = new LineController(scanner); + this.sectionController = new SectionController(scanner); + this.subwayMapController = new SubwayMapController(); + } + + public void start() { + Initialization.init(); + while (true) { + try { + MainOption option = readOption(); + if (option.isQuit()) { + break; + } + link(option); + } catch (IllegalArgumentException exception) { + outputView.printExceptionMessage(exception.getMessage()); + } + } + } + + private MainOption readOption() { + outputView.printMainOptions(); + outputView.printOptions(); + MainOption option = inputView.readOption(); + outputView.printNewLine(); + return option; + } + + private void link(MainOption option) { + linkToStationManagement(option); + linkToLineManagement(option); + linkToSectionManagement(option); + linkToSubwayMap(option); + } + + private void linkToStationManagement(MainOption option) { + if (option.isStationManagement()) { + stationController.start(); + } + } + + private void linkToLineManagement(MainOption option) { + if (option.isLineManagement()) { + lineController.start(); + } + } + + private void linkToSectionManagement(MainOption option) { + if (option.isSectionManagement()) { + sectionController.start(); + } + } + + private void linkToSubwayMap(MainOption option) { + if (option.isSubwayMap()) { + subwayMapController.start(); + } + } +} diff --git a/src/main/java/subway/section/SectionController.java b/src/main/java/subway/section/SectionController.java new file mode 100644 index 000000000..a163184ff --- /dev/null +++ b/src/main/java/subway/section/SectionController.java @@ -0,0 +1,97 @@ +package subway.section; + +import subway.station.Name; +import subway.view.section.SectionInputView; +import subway.view.section.SectionOutputView; + +import java.util.Scanner; + +public class SectionController { + + private final SectionInputView inputView; + private final SectionOutputView outputView; + private final SectionService sectionService; + + public SectionController(Scanner scanner) { + this.inputView = new SectionInputView(scanner); + this.outputView = new SectionOutputView(); + this.sectionService = new SectionService(); + } + + public void start() { + while (true) { + try { + SectionOption option = readOption(); + if (option.isBack()) { + break; + } + createSection(option); + deleteSection(option); + } catch (IllegalArgumentException exception) { + outputView.printExceptionMessage(exception.getMessage()); + } + } + } + + private SectionOption readOption() { + outputView.printSectionOption(); + outputView.printOptions(); + SectionOption option = inputView.readOption(); + outputView.printNewLine(); + return option; + } + + private void createSection(SectionOption option) { + if (option.isCreate()) { + Name lineName = readLineName(); + Name stationName = readStationName(); + int index = readIndex(); + sectionService.create(lineName, stationName, index); + outputView.printCreateSection(); + outputView.printNewLine(); + } + } + + private Name readLineName() { + outputView.printReadLineName(); + Name name = inputView.readLineName(); + outputView.printNewLine(); + return name; + } + + private Name readStationName() { + outputView.printReadStationName(); + Name name = inputView.readStationName(); + outputView.printNewLine(); + return name; + } + + private int readIndex() { + outputView.printReadIndex(); + int index = inputView.readIndex(); + outputView.printNewLine(); + return index; + } + + private void deleteSection(SectionOption option) { + if (option.isDelete()) { + sectionService.delete(readDeleteLine(), readDeleteStation()); + outputView.printDeleteSection(); + outputView.printNewLine(); + } + } + + public Name readDeleteLine() { + outputView.printDeleteSectionLine(); + Name name = inputView.readDeleteLine(); + outputView.printNewLine(); + return name; + } + + public Name readDeleteStation() { + outputView.printDeleteSectionStation(); + Name name = inputView.readDeleteStation(); + outputView.printNewLine(); + return name; + } +} diff --git a/src/main/java/subway/section/SectionOption.java b/src/main/java/subway/section/SectionOption.java new file mode 100644 index 000000000..4533894bf --- /dev/null +++ b/src/main/java/subway/section/SectionOption.java @@ -0,0 +1,48 @@ +package subway.section; + +import subway.constant.ExceptionMessage; + +import java.util.Arrays; + +public enum SectionOption { + + CREATE("1", "구간 등록"), + DELETE("2", "구간 삭제"), + + BACK("B", "돌아가기"); + + private final String option; + private final String title; + + SectionOption(String option, String title) { + this.option = option; + this.title = title; + } + + public static SectionOption getOption(String option) { + return Arrays.stream(SectionOption.values()) + .filter(value -> option.equals(value.option)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.INVALID_OPTION.toString())); + } + + public boolean isCreate() { + return this == CREATE; + } + + public boolean isDelete() { + return this == DELETE; + } + + public boolean isBack() { + return this == BACK; + } + + public String getOption() { + return option; + } + + public String getTitle() { + return title; + } +} diff --git a/src/main/java/subway/section/SectionService.java b/src/main/java/subway/section/SectionService.java new file mode 100644 index 000000000..8359b26bc --- /dev/null +++ b/src/main/java/subway/section/SectionService.java @@ -0,0 +1,16 @@ +package subway.section; + +import subway.line.LineRepository; +import subway.station.Name; +import subway.station.StationRepository; + +public class SectionService { + + public void create(Name lineName, Name stationName, int index) { + LineRepository.addStopStation(lineName, StationRepository.findByName(stationName), index); + } + + public void delete(Name lineName, Name stationName) { + LineRepository.deleteStopStation(lineName, StationRepository.findByName(stationName)); + } +} \ No newline at end of file diff --git a/src/main/java/subway/station/Name.java b/src/main/java/subway/station/Name.java new file mode 100644 index 000000000..4d9fc3b9e --- /dev/null +++ b/src/main/java/subway/station/Name.java @@ -0,0 +1,29 @@ +package subway.station; + +import subway.constant.ExceptionMessage; + +public class Name { + + private static final int MIN_LENGTH = 2; + private final String value; + + public Name(String value) { + validateName(value); + this.value = value; + } + + private void validateName(String value) { + if (value.length() < MIN_LENGTH) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_LENGTH.toString()); + } + } + + public boolean equals(Name name) { + return value.equals(name.value); + } + + @Override + public String toString() { + return value; + } +} diff --git a/src/main/java/subway/station/Station.java b/src/main/java/subway/station/Station.java new file mode 100644 index 000000000..bac540857 --- /dev/null +++ b/src/main/java/subway/station/Station.java @@ -0,0 +1,21 @@ +package subway.station; + +import subway.constant.InformationMessage; + +public class Station { + + private final Name name; + + public Station(Name name) { + this.name = name; + } + + public boolean isSame(Name name) { + return name.equals(this.name); + } + + @Override + public String toString() { + return String.format(InformationMessage.READ_ELEMENT.toString(), name.toString()); + } +} diff --git a/src/main/java/subway/station/StationController.java b/src/main/java/subway/station/StationController.java new file mode 100644 index 000000000..b89c14d5e --- /dev/null +++ b/src/main/java/subway/station/StationController.java @@ -0,0 +1,79 @@ +package subway.station; + +import subway.view.station.StationInputView; +import subway.view.station.StationOutputView; + +import java.util.Scanner; + +public class StationController { + + private final StationOutputView outputView; + private final StationInputView inputView; + private final StationService stationService; + + public StationController(Scanner scanner) { + this.outputView = new StationOutputView(); + this.inputView = new StationInputView(scanner); + this.stationService = new StationService(); + } + + public void start() { + while (true) { + try { + StationOption option = readStationOption(); + if (option.isBack()) { + break; + } + createStation(option); + deleteStation(option); + printStation(option); + } catch (IllegalArgumentException exception) { + outputView.printExceptionMessage(exception.getMessage()); + } + } + } + + private StationOption readStationOption() { + outputView.printStationOption(); + outputView.printOptions(); + StationOption option = inputView.readStationOption(); + outputView.printNewLine(); + return option; + } + + private void createStation(StationOption option) { + if (option.isCreate()) { + stationService.create(readStationName()); + outputView.printCreated(); + outputView.printNewLine(); + } + } + + private Name readStationName() { + outputView.printStationCreation(); + Name name = inputView.readStationName(); + outputView.printNewLine(); + return name; + } + + private void deleteStation(StationOption option) { + if (option.isDelete()) { + stationService.delete(readDeleteStationName()); + outputView.printDeleted(); + outputView.printNewLine(); + } + } + + private Name readDeleteStationName() { + outputView.printDeleteStation(); + Name name = inputView.readDeleteStationName(); + outputView.printNewLine(); + return name; + } + + private void printStation(StationOption option) { + if (option.isRead()) { + outputView.printStations(); + } + } +} diff --git a/src/main/java/subway/station/StationOption.java b/src/main/java/subway/station/StationOption.java new file mode 100644 index 000000000..3f6694e42 --- /dev/null +++ b/src/main/java/subway/station/StationOption.java @@ -0,0 +1,53 @@ +package subway.station; + +import subway.constant.ExceptionMessage; + +import java.util.Arrays; + +public enum StationOption { + + CREATE("1", "역 등록"), + DELETE("2", "역 삭제"), + READ("3", "역 조회"), + BACK("B", "돌아가기"); + + + private final String option; + private final String title; + + StationOption(String option, String title) { + this.option = option; + this.title = title; + } + + public static StationOption getStationOption(String option) { + return Arrays.stream(StationOption.values()) + .filter(value -> option.equals(value.option)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.INVALID_OPTION.toString())); + } + + public boolean isCreate() { + return this == CREATE; + } + + public boolean isDelete() { + return this == DELETE; + } + + public boolean isRead() { + return this == READ; + } + + public boolean isBack() { + return this == BACK; + } + + public String getOption() { + return option; + } + + public String getTitle() { + return title; + } +} diff --git a/src/main/java/subway/station/StationRepository.java b/src/main/java/subway/station/StationRepository.java new file mode 100644 index 000000000..494a64a57 --- /dev/null +++ b/src/main/java/subway/station/StationRepository.java @@ -0,0 +1,42 @@ +package subway.station; + +import subway.constant.ExceptionMessage; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class StationRepository { + private static final List stations = new ArrayList<>(); + + public static List stations() { + return Collections.unmodifiableList(stations); + } + + public static void addStation(Name name) { + validateStation(name); + stations.add(new Station(name)); + } + + private static void validateStation(Name name) { + if (isDuplicateName(name)) { + throw new IllegalArgumentException(ExceptionMessage.DUPLICATE_STATION.toString()); + } + } + + private static boolean isDuplicateName(Name name) { + return stations().stream() + .anyMatch(station -> station.isSame(name)); + } + + public static void deleteStation(Station station) { + stations.remove(station); + } + + public static Station findByName(Name name) { + return stations.stream() + .filter(station -> station.isSame(name)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ExceptionMessage.NOT_EXISTENT_STATION.toString())); + } +} diff --git a/src/main/java/subway/station/StationService.java b/src/main/java/subway/station/StationService.java new file mode 100644 index 000000000..c0f8d95ad --- /dev/null +++ b/src/main/java/subway/station/StationService.java @@ -0,0 +1,16 @@ +package subway.station; + +import subway.line.LineRepository; + +public class StationService { + + public void create(Name name) { + StationRepository.addStation(name); + } + + public void delete(Name name) { + Station station = StationRepository.findByName(name); + LineRepository.deleteStopStation(station); + StationRepository.deleteStation(station); + } +} diff --git a/src/main/java/subway/subwaymap/SubwayMapController.java b/src/main/java/subway/subwaymap/SubwayMapController.java new file mode 100644 index 000000000..11198d009 --- /dev/null +++ b/src/main/java/subway/subwaymap/SubwayMapController.java @@ -0,0 +1,12 @@ +package subway.subwaymap; + +import subway.view.subwaymap.SubwayMapOutputView; + +public class SubwayMapController { + + private final SubwayMapOutputView outputView = new SubwayMapOutputView(); + + public void start() { + outputView.printSubwayMap(); + } +} diff --git a/src/main/java/subway/view/InputView.java b/src/main/java/subway/view/InputView.java new file mode 100644 index 000000000..e3b576f2c --- /dev/null +++ b/src/main/java/subway/view/InputView.java @@ -0,0 +1,18 @@ +package subway.view; + +import subway.main.MainOption; + +import java.util.Scanner; + +public class InputView { + + private final Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } + + public MainOption readOption() { + return MainOption.getMainOption(scanner.nextLine()); + } +} diff --git a/src/main/java/subway/view/OutputView.java b/src/main/java/subway/view/OutputView.java new file mode 100644 index 000000000..7ddf0868b --- /dev/null +++ b/src/main/java/subway/view/OutputView.java @@ -0,0 +1,37 @@ +package subway.view; + +import subway.constant.OutputMessage; +import subway.constant.PrintElement; +import subway.main.MainOption; + +import java.util.Arrays; + +public class OutputView { + + public void printMainOptions() { + StringBuilder stringBuilder = new StringBuilder(); + Arrays.stream(MainOption.values()) + .forEach(value -> + stringBuilder.append(value.getOption()) + .append(PrintElement.COMMA) + .append(value.getTitle()) + .append(PrintElement.NEW_LINE) + ); + System.out.println(OutputMessage.MAIN_MESSAGE); + System.out.println(stringBuilder); + } + + public void printOptions() { + System.out.println(OutputMessage.OPTION_SELECT); + } + + public void printNewLine() { + System.out.println(); + } + + public void printExceptionMessage(String message) { + System.out.println(); + System.out.println(message); + System.out.println(); + } +} diff --git a/src/main/java/subway/view/line/LineInputView.java b/src/main/java/subway/view/line/LineInputView.java new file mode 100644 index 000000000..588b6f8af --- /dev/null +++ b/src/main/java/subway/view/line/LineInputView.java @@ -0,0 +1,37 @@ +package subway.view.line; + +import subway.line.LineOption; +import subway.station.Name; +import subway.station.Station; +import subway.station.StationRepository; + +import java.util.Scanner; + +public class LineInputView { + + private final Scanner scanner; + + public LineInputView(Scanner scanner) { + this.scanner = scanner; + } + + public LineOption readOption() { + return LineOption.getOption(scanner.nextLine()); + } + + public Name readLineName() { + return new Name(scanner.nextLine()); + } + + public Station readUpBoundStation() { + return StationRepository.findByName(new Name(scanner.nextLine())); + } + + public Station readDescendingStation() { + return StationRepository.findByName(new Name(scanner.nextLine())); + } + + public Name readDeleteStation() { + return new Name(scanner.nextLine()); + } +} diff --git a/src/main/java/subway/view/line/LineOutputView.java b/src/main/java/subway/view/line/LineOutputView.java new file mode 100644 index 000000000..b3b3ac250 --- /dev/null +++ b/src/main/java/subway/view/line/LineOutputView.java @@ -0,0 +1,76 @@ +package subway.view.line; + +import subway.constant.InformationMessage; +import subway.constant.OutputMessage; +import subway.constant.PrintElement; +import subway.line.Line; +import subway.line.LineOption; +import subway.line.LineRepository; + +import java.util.Arrays; + +public class LineOutputView { + + public void printLineOption() { + StringBuilder stringBuilder = new StringBuilder(); + Arrays.stream(LineOption.values()) + .forEach(value -> + stringBuilder.append(value.getOption()) + .append(PrintElement.COMMA) + .append(value.getTitle()) + .append(PrintElement.NEW_LINE) + ); + System.out.println(OutputMessage.LINE_MANAGEMENT_SCREEN); + System.out.println(stringBuilder); + } + + public void printOptions() { + System.out.println(OutputMessage.OPTION_SELECT); + } + + public void printReadLineName() { + System.out.println(OutputMessage.CREATE_LINE); + } + + public void printUpBoundStation() { + System.out.println(OutputMessage.UP_BOUND_STATION); + } + + public void printDescendingStation() { + System.out.println(OutputMessage.DESCENDING_STATION); + } + + public void printCreateLine() { + System.out.println(InformationMessage.COMPLETE_CREATE_STATION); + } + + public void printReadDeleteLine() { + System.out.println(OutputMessage.DELETE_LINE); + } + + public void printDeleteLine() { + System.out.println(InformationMessage.DELETE_LINE); + } + + public void printNewLine() { + System.out.println(); + } + + public void printLines() { + StringBuilder stringBuilder = new StringBuilder(); + LineRepository.lines() + .forEach(line -> appendStations(stringBuilder, line)); + System.out.println(OutputMessage.READ_LINE); + System.out.println(stringBuilder); + } + + private void appendStations(StringBuilder stringBuilder, Line line) { + stringBuilder.append(line); + } + + public void printExceptionMessage(String message) { + System.out.println(); + System.out.println(message); + System.out.println(); + } +} diff --git a/src/main/java/subway/view/section/SectionInputView.java b/src/main/java/subway/view/section/SectionInputView.java new file mode 100644 index 000000000..b20d33a28 --- /dev/null +++ b/src/main/java/subway/view/section/SectionInputView.java @@ -0,0 +1,39 @@ +package subway.view.section; + +import subway.section.SectionOption; +import subway.station.Name; + +import java.util.Scanner; + +public class SectionInputView { + + private final Scanner scanner; + + public SectionInputView(Scanner scanner) { + this.scanner = scanner; + } + + public SectionOption readOption() { + return SectionOption.getOption(scanner.nextLine()); + } + + public Name readLineName() { + return new Name(scanner.nextLine()); + } + + public Name readStationName() { + return new Name(scanner.nextLine()); + } + + public int readIndex() { + return Integer.parseInt(scanner.nextLine()); + } + + public Name readDeleteLine() { + return new Name(scanner.nextLine()); + } + + public Name readDeleteStation() { + return new Name(scanner.nextLine()); + } +} diff --git a/src/main/java/subway/view/section/SectionOutputView.java b/src/main/java/subway/view/section/SectionOutputView.java new file mode 100644 index 000000000..7b7ef0bce --- /dev/null +++ b/src/main/java/subway/view/section/SectionOutputView.java @@ -0,0 +1,68 @@ +package subway.view.section; + +import subway.constant.InformationMessage; +import subway.constant.OutputMessage; +import subway.constant.PrintElement; +import subway.section.SectionOption; + +import java.util.Arrays; + +public class SectionOutputView { + + public void printSectionOption() { + StringBuilder stringBuilder = new StringBuilder(); + Arrays.stream(SectionOption.values()) + .forEach(value -> appendValue(stringBuilder, value)); + System.out.println(OutputMessage.STATION_OPTION_SELECT); + System.out.println(stringBuilder); + } + + private void appendValue(StringBuilder stringBuilder, SectionOption option) { + stringBuilder.append(option.getOption()) + .append(PrintElement.COMMA) + .append(option.getTitle()) + .append(PrintElement.NEW_LINE); + } + + public void printOptions() { + System.out.println(OutputMessage.OPTION_SELECT); + } + + public void printReadLineName() { + System.out.println(OutputMessage.SECTION_LINE); + } + + public void printReadStationName() { + System.out.println(OutputMessage.SECTION_STATION); + } + + public void printReadIndex() { + System.out.println(OutputMessage.SECTION_INDEX); + } + + public void printCreateSection() { + System.out.println(InformationMessage.CREATE_SECTION); + } + + public void printDeleteSectionLine() { + System.out.println(OutputMessage.DELETE_SECTION_LINE); + } + + public void printDeleteSectionStation() { + System.out.println(OutputMessage.DELETE_LINE); + } + + public void printDeleteSection() { + System.out.println(InformationMessage.DELETE_SECTION); + } + + public void printNewLine() { + System.out.println(); + } + + public void printExceptionMessage(String message) { + System.out.println(); + System.out.println(message); + System.out.println(); + } +} diff --git a/src/main/java/subway/view/station/StationInputView.java b/src/main/java/subway/view/station/StationInputView.java new file mode 100644 index 000000000..fb9177fa4 --- /dev/null +++ b/src/main/java/subway/view/station/StationInputView.java @@ -0,0 +1,27 @@ +package subway.view.station; + +import subway.station.Name; +import subway.station.StationOption; + +import java.util.Scanner; + +public class StationInputView { + + private final Scanner scanner; + + public StationInputView(Scanner scanner) { + this.scanner = scanner; + } + + public StationOption readStationOption() { + return StationOption.getStationOption(scanner.nextLine()); + } + + public Name readStationName() { + return new Name(scanner.nextLine()); + } + + public Name readDeleteStationName() { + return new Name(scanner.nextLine()); + } +} diff --git a/src/main/java/subway/view/station/StationOutputView.java b/src/main/java/subway/view/station/StationOutputView.java new file mode 100644 index 000000000..b7fe46b10 --- /dev/null +++ b/src/main/java/subway/view/station/StationOutputView.java @@ -0,0 +1,68 @@ +package subway.view.station; + +import subway.constant.InformationMessage; +import subway.constant.OutputMessage; +import subway.constant.PrintElement; +import subway.station.Station; +import subway.station.StationOption; +import subway.station.StationRepository; + +import java.util.Arrays; + +public class StationOutputView { + + public void printOptions() { + System.out.println(OutputMessage.OPTION_SELECT); + } + + public void printStationOption() { + StringBuilder stringBuilder = new StringBuilder(); + Arrays.stream(StationOption.values()) + .forEach(value -> + stringBuilder.append(value.getOption()) + .append(PrintElement.COMMA) + .append(value.getTitle()) + .append(PrintElement.NEW_LINE) + ); + System.out.println(OutputMessage.STATION_OPTION_SELECT); + System.out.println(stringBuilder); + } + + public void printStationCreation() { + System.out.println(OutputMessage.CREATE_STATION); + } + + public void printCreated() { + System.out.println(InformationMessage.COMPLETE_CREATE_STATION); + } + + public void printDeleteStation() { + System.out.println(OutputMessage.DELETE_STATION); + } + + public void printDeleted() { + System.out.println(InformationMessage.COMPLETE_DELETE_STATION); + } + + public void printStations() { + StringBuilder stringBuilder = new StringBuilder(); + StationRepository.stations() + .forEach(station -> appendStations(stringBuilder, station)); + System.out.println(OutputMessage.READ_STATION); + System.out.println(stringBuilder); + } + + private void appendStations(StringBuilder stringBuilder, Station station) { + stringBuilder.append(station); + } + + public void printNewLine() { + System.out.println(); + } + + public void printExceptionMessage(String message) { + System.out.println(); + System.out.println(message); + System.out.println(); + } +} diff --git a/src/main/java/subway/view/subwaymap/SubwayMapOutputView.java b/src/main/java/subway/view/subwaymap/SubwayMapOutputView.java new file mode 100644 index 000000000..1c65e87be --- /dev/null +++ b/src/main/java/subway/view/subwaymap/SubwayMapOutputView.java @@ -0,0 +1,14 @@ +package subway.view.subwaymap; + +import subway.constant.OutputMessage; +import subway.line.LineRepository; + +public class SubwayMapOutputView { + + public void printSubwayMap() { + System.out.println(OutputMessage.SUBWAY_MAP); + System.out.println(); + LineRepository.lines() + .forEach(line -> System.out.println(line.getSubwayMap())); + } +} diff --git a/src/test/java/subway/line/LineOptionTest.java b/src/test/java/subway/line/LineOptionTest.java new file mode 100644 index 000000000..99862329c --- /dev/null +++ b/src/test/java/subway/line/LineOptionTest.java @@ -0,0 +1,72 @@ +package subway.line; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class LineOptionTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @DisplayName("사용자가 1, 2, 3, B를 입력하면 해당하는 기능을 반환한다.") + @Test + void getLineOption() { + String input = "1"; + + LineOption option = LineOption.getOption(input); + + assertThat(option).isEqualTo(LineOption.CREATE); + } + + @DisplayName("목록에 없는 옵션을 선택할 경우 예외가 발생한다.") + @Test + void lineOptionException() { + String input = "1241"; + + assertThatThrownBy(() -> LineOption.getOption(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("옵션이 CREATE 상태이면 true를 반환한다.") + @Test + void getCreateOption() { + String input = "1"; + + LineOption option = LineOption.getOption(input); + + assertThat(option.isCreate()).isTrue(); + } + + @DisplayName("옵션이 DELETE 상태이면 true를 반환한다.") + @Test + void getDeleteOption() { + String input = "2"; + + LineOption option = LineOption.getOption(input); + + assertThat(option.isDelete()).isTrue(); + } + + @DisplayName("옵션이 Read 상태이면 true를 반환한다.") + @Test + void getReadOption() { + String input = "3"; + + LineOption option = LineOption.getOption(input); + + assertThat(option.isRead()).isTrue(); + } + + @DisplayName("옵션이 Back 상태이면 true를 반환한다.") + @Test + void getBackOption() { + String input = "B"; + + LineOption option = LineOption.getOption(input); + + assertThat(option.isBack()).isTrue(); + } +} diff --git a/src/test/java/subway/line/LineRepositoryTest.java b/src/test/java/subway/line/LineRepositoryTest.java new file mode 100644 index 000000000..2f4fed53d --- /dev/null +++ b/src/test/java/subway/line/LineRepositoryTest.java @@ -0,0 +1,60 @@ +package subway.line; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.station.Name; +import subway.station.Station; +import subway.station.StationRepository; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class LineRepositoryTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @BeforeAll + public static void initStations() { + StationRepository.addStation(new Name("강남역")); + StationRepository.addStation(new Name("교대역")); + } + + @DisplayName("이미 존재하는 노선을 다시 생성할 경우 예외 발생") + @Test + void validateDuplicateStation() { + Name lineName = new Name("2호선"); + Station upBoundStation = StationRepository.findByName(new Name("강남역")); + Station descendingStation = StationRepository.findByName(new Name("교대역")); + StopStations stopStations = new StopStations(List.of(upBoundStation, descendingStation)); + + LineRepository.addLine(lineName, stopStations); + + assertThatThrownBy(() -> LineRepository.addLine(lineName, stopStations)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("존재하지 않는 노선을 삭제할 경우 예외 발생") + @Test + void deleteLineException() { + Name name = new Name("14호선"); + + assertThatThrownBy(() -> LineRepository.deleteLineByName(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("존재하지 않는 노선에 구간을 추가할 경우 예외 발생") + @Test + void addStopStationException() { + Name name = new Name("14호선"); + Station station = StationRepository.findByName(new Name("강남역")); + + assertThatThrownBy(() -> LineRepository.addStopStation(name, station, 1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } +} diff --git a/src/test/java/subway/line/LineTest.java b/src/test/java/subway/line/LineTest.java new file mode 100644 index 000000000..63804bd87 --- /dev/null +++ b/src/test/java/subway/line/LineTest.java @@ -0,0 +1,20 @@ +package subway.line; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LineTest { + +// @DisplayName("같은 이름일 경우 true를 반환한다.") +// @Test +// void checkSameName() { +// Name name = new Name("1호선"); +// List stations = List.of(new Station(new Name("교대역")), new Station(new Name("잠실역"))); +// StopStations stopStations = new StopStations(stations); +// Line line = new Line(name, stopStations); +// +// assertThat(line.isSame(new Name("1호선"))).isTrue(); +// } +} diff --git a/src/test/java/subway/line/StopStationsTest.java b/src/test/java/subway/line/StopStationsTest.java new file mode 100644 index 000000000..a20a086bf --- /dev/null +++ b/src/test/java/subway/line/StopStationsTest.java @@ -0,0 +1,92 @@ +package subway.line; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.station.Name; +import subway.station.Station; +import subway.station.StationRepository; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class StopStationsTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @BeforeAll + public static void initStations() { + StationRepository.addStation(new Name("남부터미널역")); + StationRepository.addStation(new Name("양재역")); + StationRepository.addStation(new Name("매봉역")); + } + + @DisplayName("하행 종점역과 상행 종점역이 같을 경우 예외가 발생한다.") + @Test + void sameTerminalException() { + Station upBoundStation = StationRepository.findByName(new Name("양재역")); + Station descendingStation = StationRepository.findByName(new Name("양재역")); + + assertThatThrownBy(() -> new StopStations(List.of(upBoundStation, descendingStation))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("구간에 이미 존재하는 역을 추가하면 예외가 발생한다.") + @Test + void duplicateException() { + Station upBoundStation = StationRepository.findByName(new Name("양재역")); + Station descendingStation = StationRepository.findByName(new Name("매봉역")); + StopStations stopStations = new StopStations(List.of(upBoundStation, descendingStation)); + + Station duplicateStation = StationRepository.findByName(new Name("양재역")); + int index = 1; + + assertThatThrownBy(() -> stopStations.addStation(duplicateStation, index)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("범위 밖의 순서를 입력하면 예외가 발생한다.") + @Test + void rangeException() { + Station upBoundStation = StationRepository.findByName(new Name("양재역")); + Station descendingStation = StationRepository.findByName(new Name("매봉역")); + StopStations stopStations = new StopStations(List.of(upBoundStation, descendingStation)); + + Station duplicateStation = StationRepository.findByName(new Name("남부터미널역")); + int index = 100; + + assertThatThrownBy(() -> stopStations.addStation(duplicateStation, index)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("구간 삭제 시 존재하지 않는 역을 삭제하면 예외가 발생한다.") + @Test + void deleteException() { + Station upBoundStation = StationRepository.findByName(new Name("양재역")); + Station descendingStation = StationRepository.findByName(new Name("매봉역")); + StopStations stopStations = new StopStations(List.of(upBoundStation, descendingStation)); + + Station station = StationRepository.findByName(new Name("남부터미널역")); + + assertThatThrownBy(() -> stopStations.deleteStation(station)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("입력받은 역이 구간 안에 존재하는 경우 True를 반환한다.") + @Test + void containStation() { + Station upBoundStation = StationRepository.findByName(new Name("양재역")); + Station descendingStation = StationRepository.findByName(new Name("매봉역")); + StopStations stopStations = new StopStations(List.of(upBoundStation, descendingStation)); + + Station station = StationRepository.findByName(new Name("양재역")); + + assertThat(stopStations.contain(station)).isTrue(); + } +} diff --git a/src/test/java/subway/section/SectionOptionTest.java b/src/test/java/subway/section/SectionOptionTest.java new file mode 100644 index 000000000..12e72b214 --- /dev/null +++ b/src/test/java/subway/section/SectionOptionTest.java @@ -0,0 +1,62 @@ +package subway.section; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class SectionOptionTest { + + private static final String ERROR_MESSAGE = "[ERROR]"; + + @DisplayName("사용자가 1, 2, 3, B를 입력하면 해당하는 기능을 반환한다.") + @Test + void getLineOption() { + String input = "1"; + + SectionOption option = SectionOption.getOption(input); + + assertThat(option).isEqualTo(SectionOption.CREATE); + } + + @DisplayName("목록에 없는 옵션을 선택할 경우 예외가 발생한다.") + @Test + void lineOptionException() { + String input = "1241"; + + assertThatThrownBy(() -> SectionOption.getOption(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ERROR_MESSAGE); + } + + @DisplayName("옵션이 CREATE 상태이면 true를 반환한다.") + @Test + void getCreateOption() { + String input = "1"; + + SectionOption option = SectionOption.getOption(input); + + assertThat(option.isCreate()).isTrue(); + } + + @DisplayName("옵션이 DELETE 상태이면 true를 반환한다.") + @Test + void getDeleteOption() { + String input = "2"; + + SectionOption option = SectionOption.getOption(input); + + assertThat(option.isDelete()).isTrue(); + } + + @DisplayName("옵션이 Back 상태이면 true를 반환한다.") + @Test + void getBackOption() { + String input = "B"; + + SectionOption option = SectionOption.getOption(input); + + assertThat(option.isBack()).isTrue(); + } +} diff --git a/src/test/java/subway/section/SectionRepositoryTest.java b/src/test/java/subway/section/SectionRepositoryTest.java new file mode 100644 index 000000000..12a1163b7 --- /dev/null +++ b/src/test/java/subway/section/SectionRepositoryTest.java @@ -0,0 +1,57 @@ +package subway.section; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import subway.line.Line; +import subway.line.LineRepository; +import subway.line.StopStations; +import subway.station.Name; +import subway.station.Station; +import subway.station.StationRepository; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SectionRepositoryTest { + + @BeforeAll + public static void initStations() { + StationRepository.addStation(new Name("범계역")); + StationRepository.addStation(new Name("금정역")); + StationRepository.addStation(new Name("산본역")); + + Station upBound = StationRepository.findByName(new Name("범계역")); + Station descending = StationRepository.findByName(new Name("금정역")); + StopStations stopStations = new StopStations(List.of(upBound, descending)); + + LineRepository.addLine(new Name("4호선"), stopStations); + } + + @DisplayName("구간을 추가한다.") + @Test + void addSection() { + Name lineName = new Name("4호선"); + Name stationName = new Name("산본역"); + int index = 2; + + SectionService sectionService = new SectionService(); + sectionService.create(lineName, stationName, index); + + assertThat(LineRepository.lines().size()).isEqualTo(1); + } + + @DisplayName("구간을 삭제한다.") + @Test + void deleteSection() { + Name lineName = new Name("4호선"); + Name stationName = new Name("범계역"); + SectionService sectionService = new SectionService(); + + sectionService.delete(lineName, stationName); + Station station = StationRepository.findByName(stationName); + + assertThat(LineRepository.findLineByName(lineName).isContainStation(station)).isFalse(); + } +}