diff --git a/README.md b/README.md index d6299154c..1cdacfa1d 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,24 @@
+## 구현할 기능 + +- [X] 특정 구간 사이의 차이(시간, 거리)를 저장할 클래스 +- [X] 구간 클래스 +- [X] 구간 저장소 클래스 +- [X] 역 저장소 내에 중복된 이름이 있는지 검증하는 기능 +- [X] 노선 저장소 내에 중복된 이름이 있는지 검증하는 기능 +- [X] 초기 역/노선/구간 정보를 저장할 상수 클래스 +- [X] 초기 역을 설정하는 기능 +- [X] 초기 노선을 설정하는 기능 +- [X] 초기 구간 정보를 설정하는 기능 +- [ ] 출발/도착 역을 입력받는 기능 +- [ ] 입력받은 출발/도착 역 이름이 역 저장소에 있는지 검증하는 기능 +- [ ] 경로를 탐색하려는 A 역과 B 역이 같은지 검증하는 기능 +- [ ] A 역에서 B 역까지의 경로를 최단 거리로 조회하는 기능 +- [ ] A 역에서 B 역까지의 경로를 최소 시간으로 조회하는 기능 +- [ ] 조회한 경로를 총 거리, 총 소요 시간과 함께 출력하는 기능 + ## 🚀 기능 요구사항 > 프리코스 3주차 미션에서 사용한 코드를 참고해도 무관하다. diff --git a/src/main/java/subway/domain/Gap.java b/src/main/java/subway/domain/Gap.java new file mode 100644 index 000000000..d8da36dfc --- /dev/null +++ b/src/main/java/subway/domain/Gap.java @@ -0,0 +1,20 @@ +package subway.domain; + +public class Gap { + + private final int distance; + private final int time; + + public Gap(final int distance, final int time) { + this.distance = distance; + this.time = time; + } + + public int getTime() { + return time; + } + + public int getDistance() { + return distance; + } +} diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java index 2c4a723c9..0b5ffbf89 100644 --- a/src/main/java/subway/domain/LineRepository.java +++ b/src/main/java/subway/domain/LineRepository.java @@ -4,15 +4,30 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import subway.message.ErrorMessage; public class LineRepository { + private static final List lines = new ArrayList<>(); public static List lines() { return Collections.unmodifiableList(lines); } - public static void addLine(Line line) { + public static void validateLineNameDuplicate(String lineName) throws IllegalArgumentException { + if (lineNameExists(lineName)) { + throw new IllegalArgumentException( + ErrorMessage.LINE_REPOSITORY_LINE_ALREADY_EXIST.toString() + ); + } + } + + private static boolean lineNameExists(String name) { + return lines.stream().anyMatch(line -> line.getName().equals(name)); + } + + public static void addLine(Line line) throws IllegalArgumentException { + validateLineNameDuplicate(line.getName()); lines.add(line); } diff --git a/src/main/java/subway/domain/Section.java b/src/main/java/subway/domain/Section.java new file mode 100644 index 000000000..f4d15281b --- /dev/null +++ b/src/main/java/subway/domain/Section.java @@ -0,0 +1,92 @@ +package subway.domain; + +import java.util.List; +import subway.message.ErrorMessage; + +public class Section { + + public static final int MIN_STATIONS_SIZE = 2; + public static final int MIN_GAPS_SIZE = 1; + + private final Line line; + private final List stations; + private final List gaps; + + public Section(Line line, List stations, List gaps) + throws IllegalArgumentException { + validateStationsSize(stations); + validateGapsSize(gaps); + validateDifferenceBetweenStationsSizeAndGapsSize(stations, gaps); + this.line = line; + this.stations = stations; + this.gaps = gaps; + } + + private void validateStationsSize(List stations) throws IllegalArgumentException { + if (stations.size() < MIN_STATIONS_SIZE) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_STATIONS_TOO_SMALL.toString() + ); + } + } + + private void validateGapsSize(List gaps) throws IllegalArgumentException { + if (gaps.size() < MIN_GAPS_SIZE) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_GAPS_TOO_SMALL.toString() + ); + } + } + + private void validateDifferenceBetweenStationsSizeAndGapsSize(List stations, + List gaps) throws IllegalArgumentException { + if (stations.size() != gaps.size() + 1) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_GAPS_STATIONS_DIFFERENCE.toString() + ); + } + } + + private void validateStationIndex(final int index) throws IllegalArgumentException { + if (index < 0 || index >= stations.size()) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_STATION_INDEX_OUT_OF_RANGE.toString() + ); + } + } + + public Station getStationByIndex(final int index) throws IllegalArgumentException { + validateStationIndex(index); + return stations.get(index); + } + + private void validateIndexesDifference(final int indexAhead, final int indexBehind) + throws IllegalArgumentException { + if (Integer.min(indexAhead, indexBehind) + 1 != Integer.max(indexAhead, indexBehind)) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_STATION_INDEXES_DIFFERENCE.toString() + ); + } + } + + private void validateIndexesRange(final int indexAhead, final int indexBehind) + throws IllegalArgumentException { + if (Integer.min(indexAhead, indexBehind) < 0 || + Integer.max(indexAhead, indexBehind) >= stations.size()) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_STATION_INDEX_OUT_OF_RANGE.toString() + ); + } + } + + public Gap getGapByTwoIndexes(final int indexAhead, final int indexBehind) + throws IllegalArgumentException { + validateIndexesDifference(indexAhead, indexBehind); + validateIndexesRange(indexAhead, indexBehind); + return gaps.get(Integer.min(indexAhead, indexBehind)); + } + + public Line getLine() { + return line; + } +} diff --git a/src/main/java/subway/domain/SectionRepository.java b/src/main/java/subway/domain/SectionRepository.java new file mode 100644 index 000000000..a35048398 --- /dev/null +++ b/src/main/java/subway/domain/SectionRepository.java @@ -0,0 +1,54 @@ +package subway.domain; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import subway.message.ErrorMessage; + +public class SectionRepository { + + private static final List
sections = new ArrayList<>(); + + public static List
sections() { + return Collections.unmodifiableList(sections); + } + + private static void validateSectionLineNameDuplicate(String lineName) + throws IllegalArgumentException { + if (sections.stream().anyMatch(section -> section.getLine().getName().equals(lineName))) { + throw new IllegalArgumentException( + ErrorMessage.SECTION_REPOSITORY_LINE_ALREADY_EXIST.toString() + ); + } + } + + public static void addSection(Section section) throws IllegalArgumentException { + validateSectionLineNameDuplicate(section.getLine().getName()); + sections.add(section); + } + + public static void addSectionByNames(String lineName, String[] stationNames, List gaps) + throws IllegalArgumentException { + LineRepository.validateLineNameDuplicate(lineName); + final Line sectionLine = LineRepository.lines().stream() + .filter(line -> line.getName().equals(lineName)).findFirst().get(); + final List stations = new LinkedList<>(); + Arrays.stream(stationNames).forEach(stationName -> { + StationRepository.validateStationNameDuplicate(stationName); + stations.add(StationRepository.stations().stream() + .filter(station -> station.getName().equals(stationName)).findFirst().get()); + }); + addSection(new Section(sectionLine, stations, gaps)); + } + + public static boolean deleteSectionByLineName(String lineName) { + return sections.removeIf(section -> Objects.equals(section.getLine().getName(), lineName)); + } + + public static void deleteAll() { + sections.clear(); + } +} diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java index 8ed9d103f..39d8f6ea4 100644 --- a/src/main/java/subway/domain/StationRepository.java +++ b/src/main/java/subway/domain/StationRepository.java @@ -4,15 +4,40 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import subway.message.ErrorMessage; public class StationRepository { + private static final List stations = new ArrayList<>(); public static List stations() { return Collections.unmodifiableList(stations); } - public static void addStation(Station station) { + private static boolean stationNameExists(String name) { + return stations.stream().anyMatch(station -> station.getName().equals(name)); + } + + public static void validateStationNameDuplicate(String stationName) + throws IllegalArgumentException { + if (stationNameExists(stationName)) { + throw new IllegalArgumentException( + ErrorMessage.STATION_REPOSITORY_STATION_ALREADY_EXIST.toString() + ); + } + } + + public static void validateStationNameExist(String stationName) + throws IllegalArgumentException { + if (!stationNameExists(stationName)) { + throw new IllegalArgumentException( + ErrorMessage.STATION_REPOSITORY_STATION_DOES_NOT_EXIST.toString() + ); + } + } + + public static void addStation(Station station) throws IllegalArgumentException { + validateStationNameDuplicate(station.getName()); stations.add(station); } diff --git a/src/main/java/subway/message/ErrorMessage.java b/src/main/java/subway/message/ErrorMessage.java new file mode 100644 index 000000000..13dcc050f --- /dev/null +++ b/src/main/java/subway/message/ErrorMessage.java @@ -0,0 +1,58 @@ +package subway.message; + +import subway.domain.Section; + +public enum ErrorMessage { + + // 역 관련 에러 메시지 + // STATION_INVALID_NAME_LENGTH(String.format("역 이름은 %d자 이상이어야 합니다.", MIN_STATION_NAME_LENGTH)), + + // 노선 관련 에러 메시지 + // LINE_INVALID_NAME_LENGTH(String.format("노선 이름은 %d자 이상이어야 합니다.", MIN_LINE_NAME_LENGTH)), + LINE_STATION_INDEX_OUT_OF_RANGE("역을 추가하려는 위치가 할당될 수 없는 위치입니다."), + LINE_STATION_DOES_NOT_EXIST("제거하려는 역은 해당 노선에 없는 역입니다."), + + // 구간 관련 에러 메시지 + SECTION_ITEM_DUPLICATED("구간에는 같은 역이 여러 개 존재할 수 없습니다."), + SECTION_STATIONS_TOO_SMALL(String.format("구간에는 최소 %d개의 역이 존재하여야 합니다.", Section.MIN_STATIONS_SIZE)), + SECTION_GAPS_TOO_SMALL(String.format("구간에는 최소 %d개의 간격이 존재하여야 합니다.", Section.MIN_GAPS_SIZE)), + SECTION_STATION_ALREADY_EXIST("추가하려는 역은 이미 해당 구간에 포함된 역입니다."), + SECTION_GAPS_STATIONS_DIFFERENCE("구간의 크기는 역의 크기보다 1 작아야 합니다."), + SECTION_STATION_INDEX_OUT_OF_RANGE("색인의 범위가 구간 내 역 갯수 범위를 초과했습니다."), + SECTION_STATION_INDEXES_DIFFERENCE("두 색인의 차는 1이어야 합니다."), + + // 역 저장소 관련 에러 메시지 + STATION_REPOSITORY_STATION_ALREADY_EXIST("이미 등록된 역 이름입니다."), + STATION_REPOSITORY_STATION_DOES_NOT_EXIST("존재하지 않는 역 이름입니다."), + STATION_REPOSITORY_STATION_HAS_PARENT("구간에서 사용중인 역은 삭제할 수 없습니다."), + STATION_REPOSITORY_EMPTY("역 저장소가 비어 있습니다."), + + // 노선 저장소 관련 에러 메시지 + LINE_REPOSITORY_LINE_ALREADY_EXIST("이미 등록된 노선 이름입니다."), + LINE_REPOSITORY_LINE_DOES_NOT_EXIST("존재하지 않는 노선 이름입니다."), + LINE_REPOSITORY_EMPTY("노선 저장소가 비어 있습니다."), + + // 구간 저장소 관련 에러 메시지 + SECTION_REPOSITORY_LINE_ALREADY_EXIST("추가하려는 노선은 이미 구간 내에 존재합니다."), + + // 메뉴 선택 관련 에러 메시지 + MENU_INVALID_SELECTION("선택할 수 없는 기능입니다."), + + // 입력 관련 에러 메시지 + INPUT_EMPTY_STRING("빈 문장은 입력할 수 없습니다."), + INPUT_INVALID_STRING("올바르지 않은 입력 형식입니다."), + + ; + + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return message; + } + +} diff --git a/src/main/java/subway/ui/ConsoleInput.java b/src/main/java/subway/ui/ConsoleInput.java new file mode 100644 index 000000000..fb2acbe81 --- /dev/null +++ b/src/main/java/subway/ui/ConsoleInput.java @@ -0,0 +1,22 @@ +package subway.ui; + +import java.util.Scanner; +import subway.message.ErrorMessage; + +public class ConsoleInput { + + private ConsoleInput() { + } + + public static String scanLine(final Scanner scanner) throws IllegalArgumentException { + final String lineInput = scanner.nextLine(); + validateLineInputNotEmpty(lineInput); + return lineInput; + } + + private static void validateLineInputNotEmpty(final String lineInput) { + if (lineInput.isEmpty()) { + throw new IllegalArgumentException(ErrorMessage.INPUT_EMPTY_STRING.toString()); + } + } +} diff --git a/src/main/java/subway/ui/ConsoleOutput.java b/src/main/java/subway/ui/ConsoleOutput.java new file mode 100644 index 000000000..0f819134e --- /dev/null +++ b/src/main/java/subway/ui/ConsoleOutput.java @@ -0,0 +1,38 @@ +package subway.ui; + +public class ConsoleOutput { + private static final String GENERAL_MESSAGE_HEADER = "## "; + private static final String ERROR_MESSAGE_HEADER = "[ERROR] "; + private static final String INFO_MESSAGE_HEADER = "[INFO] "; + + private static final String GENERAL_MESSAGE_MAIN = "메인 화면"; + private static final String GENERAL_MESSAGE_PATH = "경로 기준"; + + private static final String GENERAL_MESSAGE_FUNCTION = "원하는 기능을 선택하세요."; + + private ConsoleOutput() { + } + + public static void printGeneralMessage(String message) { + System.out.println(); + System.out.println(GENERAL_MESSAGE_HEADER + message); + } + + public static void printErrorMessage(String errorMessage) { + System.out.println(); + System.out.println(ERROR_MESSAGE_HEADER + errorMessage); + } + + public static void printInfoMessage(String infoMessage) { + System.out.println(INFO_MESSAGE_HEADER + infoMessage); + } + + + public static void printMainMenu() { + printGeneralMessage(GENERAL_MESSAGE_MAIN); + for (MainMenuEnum mainMenuEnum : MainMenuEnum.values()) { + System.out.println(mainMenuEnum.getShortcut() + ". " + mainMenuEnum.getName()); + } + printGeneralMessage(GENERAL_MESSAGE_FUNCTION); + } +} diff --git a/src/main/java/subway/ui/ConsoleProgram.java b/src/main/java/subway/ui/ConsoleProgram.java new file mode 100644 index 000000000..95b81c329 --- /dev/null +++ b/src/main/java/subway/ui/ConsoleProgram.java @@ -0,0 +1,20 @@ +package subway.ui; + +import java.util.Scanner; +import subway.util.Initializer; + +public class ConsoleProgram { + + private final Scanner scanner; + + public ConsoleProgram(Scanner scanner) { + this.scanner = scanner; + } + + public void run() { + Initializer.initializeRepositories(); + MainMenu mainMenu = new MainMenu(scanner); + mainMenu.run(); + } + +} diff --git a/src/main/java/subway/ui/MainMenu.java b/src/main/java/subway/ui/MainMenu.java new file mode 100644 index 000000000..31e549c40 --- /dev/null +++ b/src/main/java/subway/ui/MainMenu.java @@ -0,0 +1,38 @@ +package subway.ui; + +import java.util.Optional; +import java.util.Scanner; +import subway.message.ErrorMessage; + +public class MainMenu { + + private final Scanner scanner; + + public MainMenu(Scanner scanner) { + this.scanner = scanner; + } + + public void run() { + while (true) { + ConsoleOutput.printMainMenu(); + String userInput; + try { + userInput = ConsoleInput.scanLine(scanner); + } catch (IllegalArgumentException e) { + ConsoleOutput.printErrorMessage(e.getMessage()); + continue; + } + Optional optional = MainMenuEnum.of(userInput); + if (optional.isEmpty()) { + ConsoleOutput.printErrorMessage(ErrorMessage.INPUT_INVALID_STRING.toString()); + continue; + } + MainMenuEnum mainMenuEnum = optional.get(); + if (mainMenuEnum.equals(MainMenuEnum.EXIT)) { + break; + } + mainMenuEnum.action(scanner); + } + } + +} diff --git a/src/main/java/subway/ui/MainMenuEnum.java b/src/main/java/subway/ui/MainMenuEnum.java new file mode 100644 index 000000000..01352ae83 --- /dev/null +++ b/src/main/java/subway/ui/MainMenuEnum.java @@ -0,0 +1,53 @@ +package subway.ui; + +import static java.util.stream.Collectors.toMap; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.Scanner; + +public enum MainMenuEnum { + SEARCH_PATH("경로 조회", "1") { + @Override + public void action(final Scanner scanner) { + } + }, + EXIT("종료", "Q") { + @Override + public void action(final Scanner scanner) { + } + }, + ; + + private static final Map MAP; + + static { + Map mainMenuEnumMap = Arrays.stream(values()) + .collect(toMap(mainMenuEnum -> mainMenuEnum.shortcut, e -> e)); + MAP = Collections.unmodifiableMap(mainMenuEnumMap); + } + + private final String name; + private final String shortcut; + + MainMenuEnum(String name, String shortcut) { + this.name = name; + this.shortcut = shortcut; + } + + public static Optional of(final String shortcut) { + return Optional.ofNullable(MAP.get(shortcut)); + } + + public abstract void action(final Scanner scanner); + + public String getName() { + return name; + } + + public String getShortcut() { + return shortcut; + } +} diff --git a/src/main/java/subway/util/Constants.java b/src/main/java/subway/util/Constants.java new file mode 100644 index 000000000..c71a5806a --- /dev/null +++ b/src/main/java/subway/util/Constants.java @@ -0,0 +1,18 @@ +package subway.util; + +public class Constants { + + public static final String[] INITIAL_LINE_NAMES = {"2호선", "3호선", "신분당선"}; + public static final String[][] INITIAL_STATION_NAMES_IN_LINES = { + {"교대역", "강남역", "역삼역"}, + {"교대역", "남부터미널역", "양재역", "매봉역"}, + {"강남역", "양재역", "양재시민의숲역"} + }; + public static final int[][][] INITIAL_GAPS_BETWEEN_STATIONS_OF_SECTIONS = { + {{2, 3}, {2, 3}}, + {{3, 2}, {6, 5}, {1, 1}}, + {{2, 8}, {10, 3}} + }; + + private Constants() {} +} diff --git a/src/main/java/subway/util/Initializer.java b/src/main/java/subway/util/Initializer.java new file mode 100644 index 000000000..5fb548acb --- /dev/null +++ b/src/main/java/subway/util/Initializer.java @@ -0,0 +1,53 @@ +package subway.util; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import subway.domain.Gap; +import subway.domain.Line; +import subway.domain.LineRepository; +import subway.domain.SectionRepository; +import subway.domain.Station; +import subway.domain.StationRepository; + +public class Initializer { + + private Initializer() { + } + + private static void initializeStationRepository() { + final Set stationNameSet = new HashSet<>(); + for (final String[] stationNames : Constants.INITIAL_STATION_NAMES_IN_LINES) { + stationNameSet.addAll(Arrays.asList(stationNames)); + } + stationNameSet + .forEach(stationName -> StationRepository.addStation(new Station(stationName))); + } + + private static void initializeLineRepository() { + Arrays.asList(Constants.INITIAL_LINE_NAMES) + .forEach(lineName -> LineRepository.addLine(new Line(lineName))); + } + + + private static void initializeSectionRepository() { + for (int i = 0; i < Constants.INITIAL_LINE_NAMES.length; i++) { + final List gaps = new LinkedList<>(); + Arrays.asList(Constants.INITIAL_GAPS_BETWEEN_STATIONS_OF_SECTIONS[i]) + .forEach(gap -> gaps.add(new Gap(gap[0], gap[1]))); + SectionRepository.addSectionByNames( + Constants.INITIAL_LINE_NAMES[i], + Constants.INITIAL_STATION_NAMES_IN_LINES[i], + gaps + ); + } + } + + public static void initializeRepositories() { + initializeStationRepository(); + initializeLineRepository(); + initializeSectionRepository(); + } +} diff --git a/src/test/java/subway/domain/LineRepositoryTest.java b/src/test/java/subway/domain/LineRepositoryTest.java new file mode 100644 index 000000000..ea8ce3727 --- /dev/null +++ b/src/test/java/subway/domain/LineRepositoryTest.java @@ -0,0 +1,57 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import subway.util.Constants; + +class LineRepositoryTest { + + private static final List lines = new ArrayList<>(); + + private static final String NON_EXIST_LINE_NAME = "존재하지않는노선"; + + @BeforeAll + static void setUpBeforeAll() { + Arrays.asList(Constants.INITIAL_LINE_NAMES) + .forEach(lineName -> lines.add(new Line(lineName))); + } + + @BeforeEach + void setUp() { + LineRepository.deleteAll(); + lines.forEach(LineRepository::addLine); + } + + @Test + void addLine_NameDuplicated_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + LineRepository.addLine(lines.get(0)) + ); + } + + @Test + void addLine_ValidItem_NoExceptionThrown() { + assertThatNoException().isThrownBy(() -> + LineRepository.addLine(new Line(NON_EXIST_LINE_NAME)) + ); + } + + @Test + void deleteLineByName_InvalidItem_False() { + assertThat(LineRepository.deleteLineByName(NON_EXIST_LINE_NAME)).isFalse(); + } + + @Test + void deleteLineByName_ValidItem_True() { + assertThat(LineRepository.deleteLineByName(lines.get(0).getName())).isTrue(); + } + +} diff --git a/src/test/java/subway/domain/SectionRepositoryTest.java b/src/test/java/subway/domain/SectionRepositoryTest.java new file mode 100644 index 000000000..5913a833e --- /dev/null +++ b/src/test/java/subway/domain/SectionRepositoryTest.java @@ -0,0 +1,72 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import subway.util.Constants; + +class SectionRepositoryTest { + + private static final List
sections = new ArrayList<>(); + + @BeforeAll + static void setUpBeforeAll() { + for (int i = 0; i < Constants.INITIAL_LINE_NAMES.length; i++) { + final Line line = new Line(Constants.INITIAL_LINE_NAMES[i]); + final List stations = new LinkedList<>(); + final List gaps = new LinkedList<>(); + for (String stationName : Constants.INITIAL_STATION_NAMES_IN_LINES[i]) { + stations.add(new Station(stationName)); + } + for (int[] gap : Constants.INITIAL_GAPS_BETWEEN_STATIONS_OF_SECTIONS[i]) { + gaps.add(new Gap(gap[0], gap[1])); + } + sections.add(new Section(line, stations, gaps)); + } + } + + @BeforeEach + void setUp() { + SectionRepository.deleteAll(); + for (int i = 0; i < sections.size() - 1; i++) { + SectionRepository.addSection(sections.get(i)); + } + + } + + @Test + void addSection_NameDuplicate_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + SectionRepository.addSection(sections.get(0)) + ); + } + + @Test + void addSection_ValidItem_NoExceptionThrown() { + assertThatNoException().isThrownBy(() -> + SectionRepository.addSection(sections.get(sections.size() - 1)) + ); + } + + @Test + void deleteSectionByLineName_LineNotExist_False() { + assertThat( + SectionRepository + .deleteSectionByLineName(Constants.INITIAL_LINE_NAMES[sections.size() - 1]) + ).isFalse(); + } + + @Test + void deleteSectionByLineName_ValidName_True() { + assertThat( + SectionRepository.deleteSectionByLineName(Constants.INITIAL_LINE_NAMES[0]) + ).isTrue(); + } +} diff --git a/src/test/java/subway/domain/SectionTest.java b/src/test/java/subway/domain/SectionTest.java new file mode 100644 index 000000000..356e055ee --- /dev/null +++ b/src/test/java/subway/domain/SectionTest.java @@ -0,0 +1,75 @@ +package subway.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +import java.util.LinkedList; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class SectionTest { + + private static final String LINE_NAME = "2호선"; + private static final String[] STATION_NAMES = {"교대역", "강남역", "역삼역"}; + private static final int[][] GAPS = {{2, 3}, {2, 3}}; + private static final Line line = new Line(LINE_NAME); + private static final List stations = new LinkedList<>(); + private static final List gaps = new LinkedList<>(); + private static Section section; + + @BeforeAll + static void setUp() { + for (String stationName : STATION_NAMES) { + stations.add(new Station(stationName)); + } + for (int[] gap : GAPS) { + gaps.add(new Gap(gap[0], gap[1])); + } + section = new Section(line, stations, gaps); + } + + @Test + void getStationByIndex_ValidIndex_Pass() { + for (int i = 0; i < stations.size(); i++) { + assertThat(section.getStationByIndex(i)).isEqualTo(stations.get(i)); + } + } + + @Test + void getStationByIndex_InvalidIndex_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + section.getStationByIndex(-1) + ); + assertThatIllegalArgumentException().isThrownBy(() -> + section.getStationByIndex(stations.size()) + ); + } + + @Test + void getGapByTwoIndexes_ValidIndexes_Pass() { + assertThat(section.getGapByTwoIndexes(0, 1)).isEqualTo(gaps.get(0)); + } + + @Test + void getGapByTwoIndexes_InvalidIndexesDifference_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + section.getGapByTwoIndexes(0, 2) + ); + } + + @Test + void getGapByTwoIndexes_InvalidIndexesRange_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + section.getGapByTwoIndexes(-1, 0) + ); + assertThatIllegalArgumentException().isThrownBy(() -> + section.getGapByTwoIndexes(stations.size(), stations.size() - 1) + ); + } + + @Test + void getLine_SameLine_Pass() { + assertThat(section.getLine()).isEqualTo(line); + } +} \ 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..b9f5019d5 --- /dev/null +++ b/src/test/java/subway/domain/StationRepositoryTest.java @@ -0,0 +1,62 @@ +package subway.domain; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import subway.util.Constants; + +class StationRepositoryTest { + + private static final List stationNames = new ArrayList<>(); + private static final List stations = new ArrayList<>(); + + private static final String NON_EXIST_STATION_NAME = "존재하지않는역"; + + @BeforeAll + static void setUpBeforeAll() { + for (String[] stationNameArray : Constants.INITIAL_STATION_NAMES_IN_LINES) { + stationNames.addAll(Arrays.stream(stationNameArray) + .filter(stationName -> !stationNames.contains(stationName)) + .collect(toList())); + } + stationNames.forEach(stationName -> stations.add(new Station(stationName))); + } + + @BeforeEach + void setUp() { + StationRepository.deleteAll(); + stations.forEach(StationRepository::addStation); + } + + @Test + void addStation_NameDuplicated_ExceptionThrown() { + assertThatIllegalArgumentException().isThrownBy(() -> + StationRepository.addStation(stations.get(0)) + ); + } + + @Test + void addStation_ValidItem_NoExceptionThrown() { + assertThatNoException().isThrownBy(() -> + StationRepository.addStation(new Station(NON_EXIST_STATION_NAME)) + ); + } + + @Test + void deleteStation_InvalidItem_False() { + assertThat(StationRepository.deleteStation(NON_EXIST_STATION_NAME)).isFalse(); + } + + @Test + void deleteStation_ValidItem_True() { + assertThat(StationRepository.deleteStation(stations.get(0).getName())).isTrue(); + } +}