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();
+ }
+}