diff --git a/docs/README.md b/docs/README.md index e69de29bb..cfe9a93b1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,79 @@ +## 기능 목록 +- [x] 시작 메시지 출력 +- [x] 코치 이름 입력 요청 메시지 출력 +- [x] 코치 이름 입력 + - [x] 코치 이름 입력값 쉼표로 구분됐는지 검증 + - [x] 코치 이름 길이 2 ~ 4 사이인지 검증 + - [x] 코치 5명 이하인지 검증 + - [x] 잘못된 입력시 에러 메시지 출력 및 재시도 +- [x] 코치별 못 먹는 메뉴 입력 요청 메시지 출력 +- [x] 코치별 못 먹는 메뉴 입력 + - [x] 개수 0 ~ 2개 사이인지 검증 + - [x] 메뉴 목록에 포함된 메뉴인지 검증 + - [x] 잘못된 입력시 에러 메시지 출력 및 재시도 +- [x] 메뉴 추천 + - [x] 랜덤 메뉴 생성 + - [x] 한 주에 같은 카테고리 최대 2회인지 검증 + - [x] 각 코치에게 중복된 메뉴가 없는지 검증 +- [x] 추천 완료 메시지 출력 + +## 구현 클래스 + +- MenuController + - run() + +- OutputView + - printStart() + - printCoachNameRequest() + +- Coach + - getName() + - hasName() + - updateHateMenus() + - getHateMenus() + - updateRecommendedMenus() + +- Coaches + - getNextCoachName() + - hasNext() + - findByName() + - initIndex() + - getNextCoach() + +- InputValidator + - validateInputDelimiter() + +- InputView + - readCoachNames() + +- InputManager + - readCoachNames() + +- MenuService + - saveCoaches() + +- MenuRepository + - saveCoaches() + +- Menu + - getName() + +- HateMenus + +- RandomMenuGenerator + +- RecommendedMenus + - addMenu() + +- MenuCategories + - hasMaxNum() + - addRecommendedMenus() + - needNext() + +- RecommendResult + - getResult() + +## 열거형 목록 +- GameMessage +- ErrorMessage +- MenuCategory diff --git a/src/main/java/menu/Application.java b/src/main/java/menu/Application.java index 6340b6f33..78489c916 100644 --- a/src/main/java/menu/Application.java +++ b/src/main/java/menu/Application.java @@ -1,7 +1,9 @@ package menu; +import menu.controller.MenuController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + new MenuController().run(); } } diff --git a/src/main/java/menu/constant/ErrorMessage.java b/src/main/java/menu/constant/ErrorMessage.java new file mode 100644 index 000000000..a0c843349 --- /dev/null +++ b/src/main/java/menu/constant/ErrorMessage.java @@ -0,0 +1,22 @@ +package menu.constant; + +public enum ErrorMessage { + INVALID_COACH_NAME_LENGTH("코치 이름 길이가 잘못되었습니다."), + INVALID_COACH_NUM("코치의 인원수가 잘못되었거나 중복 코치이름이 있습니다."), + INVALID_INPUT_DELIMITER_USAGE("쉼표는 맨 처음이나 끝에 올 수 없습니다."), + INVALID_MENU_SIZE("못 먹는 메뉴의 개수가 잘못되었습니다."), + INVALID_MENU_NAME("존재하지 않는 메뉴입니다."), + INVALID_COACH_NAME("존재하지 않는 코치 이름입니다."), + INVALID_CATEGORY_INDEX("카테고리 인덱스가 잘못되었습니다."); + + private static final String ERROR_PREFIX = "[ERROR] "; + private final String message; + + ErrorMessage(final String message) { + this.message = message; + } + + public String getMessage() { + return ERROR_PREFIX + this.message; + } +} diff --git a/src/main/java/menu/constant/GameMessage.java b/src/main/java/menu/constant/GameMessage.java new file mode 100644 index 000000000..a00b7eb14 --- /dev/null +++ b/src/main/java/menu/constant/GameMessage.java @@ -0,0 +1,20 @@ +package menu.constant; + +public enum GameMessage { + START("점심 메뉴 추천을 시작합니다."), + COACH_NAME_REQUEST("코치의 이름을 입력해 주세요. (, 로 구분)"), + COACH_HATE_MENU_REQUEST("%s(이)가 못 먹는 메뉴를 입력해 주세요."), + MENU_RECOMMEND_RESULT("메뉴 추천 결과입니다."), + RECOMMEND_DAYS("[ 구분 | 월요일 | 화요일 | 수요일 | 목요일 | 금요일 ]"), + RECOMMEND_FINISH("추천을 완료했습니다."); + + private final String message; + + GameMessage(final String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/menu/constant/MenuCategory.java b/src/main/java/menu/constant/MenuCategory.java new file mode 100644 index 000000000..7a3e86b55 --- /dev/null +++ b/src/main/java/menu/constant/MenuCategory.java @@ -0,0 +1,47 @@ +package menu.constant; + +import menu.domain.HateMenus; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public enum MenuCategory { + JAPANESE_FOOD(1, "일식", List.of("규동", "우동", "미소시루", "스시", "가츠동", "오니기리", "하이라이스", "라멘", "오코노미야끼")), + KOREAN_FOOD(2, "한식", List.of("김밥", "김치찌개", "쌈밥", "된장찌개", "비빔밥", "칼국수", "불고기", "떡볶이", "제육볶음")), + CHINESE_FOOD(3, "중식", List.of("깐풍기", "볶음면", "동파육", "짜장면", "짬뽕", "마파두부", "탕수육", "토마토 달걀볶음", "고추잡채")), + ASIAN_FOOD(4, "아시안", List.of("팟타이", "카오 팟", "나시고렝", "파인애플 볶음밥", "쌀국수", "똠얌꿍", "반미", "월남쌈", "분짜")), + WESTERN_FOOD(5, "양식", List.of("라자냐", "그라탱", "뇨끼", "끼슈", "프렌치 토스트", "바게트", "스파게티", "피자", "파니니")); + + private final int index; + private final String category; + private final List menus; + + MenuCategory(final int index, final String category, final List menus) { + this.index = index; + this.category = category; + this.menus = menus; + } + + public static boolean isNotExistMenu(final String menuName) { + return Arrays.stream(values()) + .noneMatch(mc -> mc.menus.contains(menuName)); + } + + public List getMenusFiltered(final HateMenus hateMenus) { + return this.menus.stream() + .filter(hateMenus::hasNoSameMenu) + .collect(Collectors.toList()); + } + + public static MenuCategory getByIndex(final int index) { + return Arrays.stream(values()) + .filter(mc -> mc.index == index) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.INVALID_CATEGORY_INDEX.getMessage())); + } + + public String getCategoryName() { + return this.category; + } +} diff --git a/src/main/java/menu/controller/MenuController.java b/src/main/java/menu/controller/MenuController.java new file mode 100644 index 000000000..579b63eba --- /dev/null +++ b/src/main/java/menu/controller/MenuController.java @@ -0,0 +1,42 @@ +package menu.controller; + +import menu.domain.Coaches; +import menu.domain.HateMenus; +import menu.domain.RecommendResult; +import menu.io.InputManager; +import menu.io.OutputView; +import menu.service.MenuService; + +public class MenuController { + + private final OutputView outputView = new OutputView(); + private final InputManager inputManager = new InputManager(); + private final MenuService menuService = new MenuService(); + + public void run() { + outputView.printStart(); + final Coaches coaches = createCoaches(); + createHateMenu(coaches); + recommendMenu(); + } + + private void recommendMenu() { + final RecommendResult recommendResult = menuService.recommendMenu(); + outputView.printRecommendResult(recommendResult); + } + + private void createHateMenu(final Coaches coaches) { + while (!coaches.isLast()) { + final String coachName = coaches.getNextCoachName(); + outputView.printCoachHateMenuRequest(coachName); + final HateMenus hateMenus = inputManager.readCoachHateMenu(); + menuService.updateHateMenus(coachName, hateMenus); + } + } + + private Coaches createCoaches() { + outputView.printCoachNameRequest(); + final Coaches coaches = inputManager.readCoachNames(); + return menuService.saveCoaches(coaches); + } +} diff --git a/src/main/java/menu/domain/Coach.java b/src/main/java/menu/domain/Coach.java new file mode 100644 index 000000000..9498a8470 --- /dev/null +++ b/src/main/java/menu/domain/Coach.java @@ -0,0 +1,68 @@ +package menu.domain; + +import menu.constant.ErrorMessage; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class Coach { + + private static final int MIN_NAME_LENGTH = 2; + private static final int MAX_NAME_LENGTH = 4; + private final String name; + private HateMenus hateMenus; + private RecommendedMenus recommendedMenus; + + public Coach(final String name) { + validateName(name); + this.name = name; + this.recommendedMenus = new RecommendedMenus(); + } + + private void validateName(final String name) { + final int length = name.length(); + if (MIN_NAME_LENGTH > length || length > MAX_NAME_LENGTH) { + throw new IllegalArgumentException(ErrorMessage.INVALID_COACH_NAME_LENGTH.getMessage()); + } + } + + public String getName() { + return this.name; + } + + public boolean hasName(final String coachName) { + return this.name.equals(coachName); + } + + public void updateHateMenus(final HateMenus hateMenus) { + this.hateMenus = hateMenus; + } + + public HateMenus getHateMenus() { + return this.hateMenus; + } + + public void updateRecommendedMenus(final String menus) { + this.recommendedMenus.addMenu(menus); + } + + public List getRecommendedMenus() { + return this.recommendedMenus.getMenus().stream() + .map(Menu::getName) + .collect(Collectors.toList()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Coach coach = (Coach) o; + return Objects.equals(name, coach.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/src/main/java/menu/domain/Coaches.java b/src/main/java/menu/domain/Coaches.java new file mode 100644 index 000000000..0b767ca0a --- /dev/null +++ b/src/main/java/menu/domain/Coaches.java @@ -0,0 +1,64 @@ +package menu.domain; + +import menu.constant.ErrorMessage; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +public class Coaches { + + private static final int MIN_COACH_NUM = 2; + private static final int MAX_COACH_NUM = 5; + private static final int INIT_INDEX = 0; + private final List coaches; + private int currentIndex; + + public Coaches(final List coaches) { + validate(coaches); + this.coaches = Collections.unmodifiableList(coaches); + this.currentIndex = INIT_INDEX; + } + + private void validate(final List coaches) { + final int size = coaches.size(); + if (size < MIN_COACH_NUM || size > MAX_COACH_NUM || new HashSet<>(coaches).size() != coaches.size()) { + throw new IllegalArgumentException(ErrorMessage.INVALID_COACH_NUM.getMessage()); + } + } + + public String getNextCoachName() { + checkCurrentIndex(); + return coaches.get(currentIndex++).getName(); + } + + private void checkCurrentIndex() { + if (currentIndex == coaches.size()) { + currentIndex = INIT_INDEX; + } + } + + public boolean isLast() { + final boolean flag = currentIndex == coaches.size(); + if (flag) { + currentIndex = INIT_INDEX; + } + return flag; + } + + public Coach findByName(final String coachName) { + return this.coaches.stream() + .filter(coach -> coach.hasName(coachName)) + .findAny() + .orElseThrow(() -> new IllegalStateException(ErrorMessage.INVALID_COACH_NAME.getMessage())); + } + + public Coach getNextCoach() { + checkCurrentIndex(); + return this.coaches.get(currentIndex++); + } + + public List getCoaches() { + return this.coaches; + } +} diff --git a/src/main/java/menu/domain/HateMenus.java b/src/main/java/menu/domain/HateMenus.java new file mode 100644 index 000000000..da62bda93 --- /dev/null +++ b/src/main/java/menu/domain/HateMenus.java @@ -0,0 +1,29 @@ +package menu.domain; + +import menu.constant.ErrorMessage; + +import java.util.List; +import java.util.stream.Collectors; + +public class HateMenus { + + private static final int MAX_HATE_MENU_SIZE = 2; + private final List menus; + + public HateMenus(final List menus) { + validateSize(menus); + this.menus = menus.stream().map(Menu::new).collect(Collectors.toList()); + } + + private void validateSize(final List menus) { + if (menus.size() > MAX_HATE_MENU_SIZE) { + throw new IllegalArgumentException(ErrorMessage.INVALID_MENU_SIZE.getMessage()); + } + } + + public boolean hasNoSameMenu(final String menuName) { + return menus.stream() + .map(Menu::getName) + .noneMatch(menuName::equals); + } +} diff --git a/src/main/java/menu/domain/Menu.java b/src/main/java/menu/domain/Menu.java new file mode 100644 index 000000000..a26e61cbc --- /dev/null +++ b/src/main/java/menu/domain/Menu.java @@ -0,0 +1,23 @@ +package menu.domain; + +import menu.constant.ErrorMessage; +import menu.constant.MenuCategory; + +public class Menu { + private final String name; + + public Menu(final String name) { + validateName(name); + this.name = name; + } + + private void validateName(final String name) { + if (MenuCategory.isNotExistMenu(name)) { + throw new IllegalArgumentException(ErrorMessage.INVALID_MENU_NAME.getMessage()); + } + } + + public String getName() { + return this.name; + } +} diff --git a/src/main/java/menu/domain/MenuCategories.java b/src/main/java/menu/domain/MenuCategories.java new file mode 100644 index 000000000..c4a7ba665 --- /dev/null +++ b/src/main/java/menu/domain/MenuCategories.java @@ -0,0 +1,35 @@ +package menu.domain; + +import menu.constant.MenuCategory; + +import java.util.ArrayList; +import java.util.List; + +public class MenuCategories { + + private static final Long MAX_COUNT = 2L; + private static final Integer DAY_COUNT = 5; + private final List menuCategories; + + public MenuCategories() { + this.menuCategories = new ArrayList<>(); + } + + public boolean hasMaxNum(final MenuCategory menuCategory) { + return menuCategories.stream() + .filter(mc -> mc == menuCategory) + .count() == MAX_COUNT; + } + + public boolean needNext() { + return menuCategories.size() < DAY_COUNT; + } + + public List getMenuCategories() { + return this.menuCategories; + } + + public void addMenuCategory(final MenuCategory menuCategory) { + menuCategories.add(menuCategory); + } +} diff --git a/src/main/java/menu/domain/RecommendResult.java b/src/main/java/menu/domain/RecommendResult.java new file mode 100644 index 000000000..78f987653 --- /dev/null +++ b/src/main/java/menu/domain/RecommendResult.java @@ -0,0 +1,30 @@ +package menu.domain; + +import menu.constant.MenuCategory; + +import java.util.stream.Collectors; + +public class RecommendResult { + + private static final String START_TAG = "[ "; + private static final String DELIMITER_TAG = " | "; + private static final String END_TAG = " ]"; + private static final String NEW_LINE = "\n"; + private static final String CATEGORY = "카테고리"; + private final Coaches coaches; + private final MenuCategories menuCategories; + + public RecommendResult(final Coaches coaches, final MenuCategories menuCategories) { + this.coaches = coaches; + this.menuCategories = menuCategories; + } + + public String getResult() { + return START_TAG + CATEGORY + DELIMITER_TAG + menuCategories.getMenuCategories().stream() + .map(MenuCategory::getCategoryName) + .collect(Collectors.joining(DELIMITER_TAG)) + END_TAG + NEW_LINE + + coaches.getCoaches().stream() + .map(coach -> START_TAG + coach.getName() + DELIMITER_TAG + String.join(DELIMITER_TAG, coach.getRecommendedMenus()) + END_TAG) + .collect(Collectors.joining(NEW_LINE)) + NEW_LINE; + } +} diff --git a/src/main/java/menu/domain/RecommendedMenus.java b/src/main/java/menu/domain/RecommendedMenus.java new file mode 100644 index 000000000..f77f57f74 --- /dev/null +++ b/src/main/java/menu/domain/RecommendedMenus.java @@ -0,0 +1,20 @@ +package menu.domain; + +import java.util.ArrayList; +import java.util.List; + +public class RecommendedMenus { + private final List recommendedMenus; + + public RecommendedMenus() { + this.recommendedMenus = new ArrayList<>(); + } + + public void addMenu(final String menuName) { + recommendedMenus.add(new Menu(menuName)); + } + + public List getMenus() { + return this.recommendedMenus; + } +} diff --git a/src/main/java/menu/io/InputManager.java b/src/main/java/menu/io/InputManager.java new file mode 100644 index 000000000..131300e89 --- /dev/null +++ b/src/main/java/menu/io/InputManager.java @@ -0,0 +1,38 @@ +package menu.io; + +import menu.domain.Coach; +import menu.domain.Coaches; +import menu.domain.HateMenus; + +import java.util.Arrays; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class InputManager { + + private static final String INPUT_DELIMITER = ","; + private final InputView inputView = new InputView(); + + public Coaches readCoachNames() { + return read(() -> { + final String input = inputView.readCoachNames(); + return new Coaches(Arrays.stream(input.split(INPUT_DELIMITER)) + .map(Coach::new) + .collect(Collectors.toList())); + }); + } + + public HateMenus readCoachHateMenu() { + return read(() -> new HateMenus(Arrays.asList(inputView.readHateMenus().split(INPUT_DELIMITER)))); + } + + private T read(final Supplier supplier) { + while (true) { + try { + return supplier.get(); + } catch (final IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } +} diff --git a/src/main/java/menu/io/InputValidator.java b/src/main/java/menu/io/InputValidator.java new file mode 100644 index 000000000..38905c259 --- /dev/null +++ b/src/main/java/menu/io/InputValidator.java @@ -0,0 +1,21 @@ +package menu.io; + +import menu.constant.ErrorMessage; + +public class InputValidator { + + private static final String INPUT_DELIMITER = ","; + + public void validateHateMenus(final String input) { + if (input.isEmpty()) { + return; + } + validateInputDelimiter(input); + } + + public void validateInputDelimiter(final String input) { + if (input.startsWith(INPUT_DELIMITER) || input.endsWith(INPUT_DELIMITER)) { + throw new IllegalArgumentException(ErrorMessage.INVALID_INPUT_DELIMITER_USAGE.getMessage()); + } + } +} diff --git a/src/main/java/menu/io/InputView.java b/src/main/java/menu/io/InputView.java new file mode 100644 index 000000000..15c6d1d2b --- /dev/null +++ b/src/main/java/menu/io/InputView.java @@ -0,0 +1,20 @@ +package menu.io; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + private final InputValidator inputValidator = new InputValidator(); + + public String readCoachNames() { + final String input = Console.readLine(); + inputValidator.validateInputDelimiter(input); + return input; + } + + public String readHateMenus() { + final String input = Console.readLine(); + inputValidator.validateHateMenus(input); + return input; + } +} diff --git a/src/main/java/menu/io/OutputView.java b/src/main/java/menu/io/OutputView.java new file mode 100644 index 000000000..9ed5edae2 --- /dev/null +++ b/src/main/java/menu/io/OutputView.java @@ -0,0 +1,26 @@ +package menu.io; + +import menu.constant.GameMessage; +import menu.domain.RecommendResult; + +public class OutputView { + + public void printStart() { + System.out.println(GameMessage.START.getMessage()); + } + + public void printCoachNameRequest() { + System.out.println(GameMessage.COACH_NAME_REQUEST.getMessage()); + } + + public void printCoachHateMenuRequest(final String coachName) { + System.out.println(String.format(GameMessage.COACH_HATE_MENU_REQUEST.getMessage(), coachName)); + } + + public void printRecommendResult(final RecommendResult recommendResult) { + System.out.println(GameMessage.MENU_RECOMMEND_RESULT.getMessage()); + System.out.println(GameMessage.RECOMMEND_DAYS.getMessage()); + System.out.println(recommendResult.getResult()); + System.out.println(GameMessage.RECOMMEND_FINISH.getMessage()); + } +} diff --git a/src/main/java/menu/repository/MenuRepository.java b/src/main/java/menu/repository/MenuRepository.java new file mode 100644 index 000000000..5f11f6974 --- /dev/null +++ b/src/main/java/menu/repository/MenuRepository.java @@ -0,0 +1,17 @@ +package menu.repository; + +import menu.domain.Coaches; + +public class MenuRepository { + + private Coaches coaches; + + public Coaches saveCoaches(final Coaches coaches) { + this.coaches = coaches; + return this.coaches; + } + + public Coaches findCoaches() { + return this.coaches; + } +} diff --git a/src/main/java/menu/service/MenuService.java b/src/main/java/menu/service/MenuService.java new file mode 100644 index 000000000..56023dd84 --- /dev/null +++ b/src/main/java/menu/service/MenuService.java @@ -0,0 +1,25 @@ +package menu.service; + +import menu.domain.*; +import menu.repository.MenuRepository; +import menu.utils.MenuRecommender; + +public class MenuService { + + private final MenuRepository menuRepository = new MenuRepository(); + private final MenuRecommender menuRecommender = new MenuRecommender(); + + public Coaches saveCoaches(final Coaches coaches) { + return menuRepository.saveCoaches(coaches); + } + + public void updateHateMenus(final String coachName, final HateMenus hateMenus) { + final Coach coach = menuRepository.findCoaches().findByName(coachName); + coach.updateHateMenus(hateMenus); + } + + public RecommendResult recommendMenu() { + final Coaches coaches = menuRepository.findCoaches(); + return menuRecommender.recommendMenus(coaches); + } +} diff --git a/src/main/java/menu/utils/MenuRecommender.java b/src/main/java/menu/utils/MenuRecommender.java new file mode 100644 index 000000000..5d37348b7 --- /dev/null +++ b/src/main/java/menu/utils/MenuRecommender.java @@ -0,0 +1,53 @@ +package menu.utils; + +import camp.nextstep.edu.missionutils.Randoms; +import menu.constant.MenuCategory; +import menu.domain.*; + +import java.util.List; + +public class MenuRecommender { + + private static final int MIN_CATEGORY_INDEX = 1; + private static final int MAX_CATEGORY_INDEX = 5; + private static final int RECOMMEND_INDEX = 0; + + public RecommendResult recommendMenus(final Coaches coaches) { + final MenuCategories menuCategories = new MenuCategories(); + recommendAllDay(coaches, menuCategories); + return new RecommendResult(coaches, menuCategories); + } + + private void recommendAllDay(final Coaches coaches, final MenuCategories menuCategories) { + while (menuCategories.needNext()) { + final MenuCategory menuCategory = generateRandomCategory(); + if (!menuCategories.hasMaxNum(menuCategory)) { + menuCategories.addMenuCategory(menuCategory); + recommendAllCoaches(coaches, menuCategory); + } + } + } + + private void recommendAllCoaches(final Coaches coaches, final MenuCategory menuCategory) { + while(!coaches.isLast()) { + final Coach coach = coaches.getNextCoach(); + final HateMenus hateMenus = coach.getHateMenus(); + final List menus = menuCategory.getMenusFiltered(hateMenus); + final String recommendedMenu = getRecommendedMenu(menus, coach.getRecommendedMenus()); + coach.updateRecommendedMenus(recommendedMenu); + } + } + + private String getRecommendedMenu(final List menus, final List recommended) { + while (true) { + final String menu = Randoms.shuffle(menus).get(RECOMMEND_INDEX); + if (!recommended.contains(menu)) { + return menu; + } + } + } + + private MenuCategory generateRandomCategory() { + return MenuCategory.getByIndex(Randoms.pickNumberInRange(MIN_CATEGORY_INDEX, MAX_CATEGORY_INDEX)); + } +} diff --git a/src/test/java/menu/domain/CoachTest.java b/src/test/java/menu/domain/CoachTest.java new file mode 100644 index 000000000..9bae8d939 --- /dev/null +++ b/src/test/java/menu/domain/CoachTest.java @@ -0,0 +1,23 @@ +package menu.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("코치 도메인에서") +class CoachTest { + + @Test + @DisplayName("생성시 이름의 길이가 4보다 크면 예외를 던진다.") + void createLongName() { + Assertions.assertThatThrownBy(() -> new Coach("가나다라마")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("생성시 이름의 길이가 2보다 작으면 예외를 던진다.") + void createShortName() { + Assertions.assertThatThrownBy(() -> new Coach("가")) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file diff --git a/src/test/java/menu/domain/CoachesTest.java b/src/test/java/menu/domain/CoachesTest.java new file mode 100644 index 000000000..9de781830 --- /dev/null +++ b/src/test/java/menu/domain/CoachesTest.java @@ -0,0 +1,18 @@ +package menu.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +@DisplayName("코치 일급컬렉션에서") +class CoachesTest { + + @Test + @DisplayName("생성시 중복되는 코치의 이름이 있으면 예외를 던진다.") + void create() { + Assertions.assertThatThrownBy(() -> new Coaches(List.of(new Coach("가나다"), new Coach("가나다")))) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/menu/domain/HateMenusTest.java b/src/test/java/menu/domain/HateMenusTest.java new file mode 100644 index 000000000..d7d382629 --- /dev/null +++ b/src/test/java/menu/domain/HateMenusTest.java @@ -0,0 +1,18 @@ +package menu.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +@DisplayName("못먹는 메뉴 도메인에서") +class HateMenusTest { + + @Test + @DisplayName("생성시 리스트의 원소 개수가 5개보다 많으면 예외를 던진다.") + void create() { + Assertions.assertThatThrownBy(() -> new HateMenus(List.of("", "", "", "", "", ""))) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/menu/domain/MenuTest.java b/src/test/java/menu/domain/MenuTest.java new file mode 100644 index 000000000..ec2dbc81c --- /dev/null +++ b/src/test/java/menu/domain/MenuTest.java @@ -0,0 +1,16 @@ +package menu.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("메뉴 도메인에서") +class MenuTest { + + @Test + @DisplayName("생성시 없는 메뉴이름으로 생성하면 예외를 던진다.") + void create() { + Assertions.assertThatThrownBy(() -> new Menu("가나다")) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/menu/io/InputValidatorTest.java b/src/test/java/menu/io/InputValidatorTest.java new file mode 100644 index 000000000..b1a058a76 --- /dev/null +++ b/src/test/java/menu/io/InputValidatorTest.java @@ -0,0 +1,34 @@ +package menu.io; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("입력값 검증 중에") +class InputValidatorTest { + + private final InputValidator inputValidator = new InputValidator(); + + @Test + @DisplayName("쉼표로 시작하면 예외를 던진다.") + void validateInputDelimiter() { + Assertions.assertThatThrownBy(() -> inputValidator.validateInputDelimiter(",abc,ase")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("공백에 대해 예외를 던지지 않는다.") + void validateHateMenusBlank() { + inputValidator.validateHateMenus(""); + Assertions.assertThatNoException(); + } + + @Test + @DisplayName("쉼표로 끝나면 예외를 던진다.") + void validateHateMenus() { + Assertions.assertThatThrownBy(() -> inputValidator.validateHateMenus("abc,ase,")) + .isInstanceOf(IllegalArgumentException.class); + } +}