diff --git a/README.md b/README.md index b722ac00..1b3f979a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # 미션 - 워들 +## 페어 프로그래밍 룰 +- [룰](./readme/PairProgrammingRule.md) + +## 기능 명세 +- [기능 설명](./readme/FunctionDescription.md) +- [클래스 설명](./readme/ClassDescription.md) + ## 🔍 진행 방식 - 미션은 **기능 요구 사항, 프로그래밍 요구 사항, 과제 진행 요구 사항** 세 가지로 구성되어 있다. diff --git a/readme/ClassDescription.md b/readme/ClassDescription.md new file mode 100644 index 00000000..9342fe3e --- /dev/null +++ b/readme/ClassDescription.md @@ -0,0 +1,50 @@ +# 기능 설명 + +### controller +1. GameHost +- GameService를 통해 게임을 실행한다. + +### service +1. GameService +- 여러 Backend / UI Serice를 사용하여 게임을 실행한다. + +### backend +1. InputManager +- 사용자의 입력을 Word 객체로 전달 받는다 +2. InputViewManger +- ViewManger을 주입받는다. +- 단어 입력 전 / 후 출력을 관리하고, InputManager을 통해 단어를 받는다. +3. WordsGenerator +- 날짜에 따라 오늘의 정답 단어를 AnswerWord로 추출한다 + +### ui +1. ViewManger +- 사용자에게 출력하는 모든 로직을 담당한다 + +### domain +1. Word +- 입력받은 단어에 대해 저장 및 검증 +2. AnswerWord +- Word를 상속받아, 다른 Word와의 비교 결과를 산출 +3. Result +- 사용자의 입력 하나에 대한 게임 결과를 저장 +4. TileColor +- Enum으로써, TileColor 별 표시 할 데이터를 저장 +5. Coin +- 문자 입력 가능 횟수를 의미 +- 최초 코인 개수를 통해 생성 +- 문자 입력시 코인 개수 감소 +- 코인이 남아있는지 여부 확인 +6. User +- Coin을 가지고 게임을 수행한다. +7. GameHost +- AnswerWord를 초기화 한다 +- 사용자의 입력에 대해 정답과 비교하여, 결과를 출력한다. + +### utils +1. FileUtils +- 파일 경로를 받아 Stream을 반환 +2. LocalDateTimeUtils +- 입력받은 2개의 날짜 차이를 반환 +3. StringUtils +- 입력받은 문자에 대해 5개의 소문자로 구성된 문자인지 검증 \ No newline at end of file diff --git a/readme/FunctionDescription.md b/readme/FunctionDescription.md new file mode 100644 index 00000000..0a48d366 --- /dev/null +++ b/readme/FunctionDescription.md @@ -0,0 +1,21 @@ +# 기능 명세 + +### 정답 단어 추출하기 +1. 파일로부터 String데이터를 읽어와야 한다. +2. 파일로부터 읽어온 데이터중, (2021-6-19 과 오늘 날짜의 차이) % (파일로부터 읽어온 String 개수) 의 위치에 있는 단어를 정답 단어로 선출한다. + +### 단어 입력받기 +1. 사용자로부터 단어를 입력을 받는다. 단, 소문자 5개로 구성된 단어야만 한다. +2. 정상적이지 않은 입력이 발생했을때, 다시 입력을 받아야 한다. + +### 정답 단어와 사용자가 입력한 단어 비교하기 +1. 정답 단어와 사용자의 단어를 비교했을때, 위치까지 똑같은 Spelling과 위치는 다르나 정답 단어에 존재하는 Spelling 그리고 아예 관계없는 Spelling을 구분한 결과값이 있어야 한다. + +### 게임 결과를 출력하기 +1. 정답 단어와 사용자의 단어 비교 결과를 색깔 박스를 통해 표시를 해주어야 한다. +2. 결과 출력시, 이전 결과도 함께 출력 해 주어야 한다. +3. 유저의 게임 성공, 실패에 대한 결과 출력 및 실패시 엔 오늘의 단어도 같이 출력 + +### 게임 횟수 제한하기 +1. 사용자가 최대 6번까지 입력 받을 수 있게 제한. 6번 이내에 클리어 시 게임 종료. + diff --git a/readme/PairProgrammingRule.md b/readme/PairProgrammingRule.md new file mode 100644 index 00000000..726865fc --- /dev/null +++ b/readme/PairProgrammingRule.md @@ -0,0 +1,36 @@ +# 페어프로그래밍 룰 + +### 네비게이터 +1. 오류를 너무 빨리 체크하지 말자 +2. 높은 추상화 수준의 지시를 하자(큰 그림을 제안하자) +3. 자신의 키보드를 사용하자 + +### 드라이버 +1. 천천히 코딩하자. 네비게이터와 항상 말을 하면서 코딩하자 +2. 네비게이터가 말이 없다면 동기화가 안된것. 동기화를 다시 하고 드라이빙하자 +3. 휴식하자. +4. 경청하자. 네비게이터가 제안할때는 키보드에서 손을 떼자. + + +### 네비게이터 & 드라이버 +1. 시작하기 전에 모든 알림을 끄자. (필요한 어플만 켜놓자) +2. 자주 역할을 전환하자. (시간을 정해두고) +3. 항상 설계를 합의하고 시작하자. +--- +- [codeStyle](https://github.com/google/styleguide/blob/gh-pages/intellij-java-google-style.xml) +- 페어그래밍 툴 : Intellij Code With Me +- 각자 20분 코딩 & 10분회고 & 10분 휴식 +- 회고 10분이 넘어가면 다시 처음부터 회고 +- 자바 코드 컨벤션을 지키면서 프로그래밍한다. + - 기본적으로 Google Java Style Guide을 원칙으로 한다. + - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. +- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다. + - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. + - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. +- 3항 연산자를 쓰지 않는다. +- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. + - 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다. +- else 예약어를 쓰지 않는다. + - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. + - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. + diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000..57b16b5a --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,22 @@ +import com.wodle.controller.GameHost; +import com.wodle.backend.InputManagerImpl; +import com.wodle.backend.InputMangerProxy; +import com.wodle.ui.ViewManagerImpl; +import com.wodle.backend.WordGeneratorImpl; + +public class Application { + + public static void main(String[] args) { + ViewManagerImpl viewManager = new ViewManagerImpl(); + InputManagerImpl inputMangerProxy = new InputMangerProxy(viewManager); + WordGeneratorImpl wordGenerator = new WordGeneratorImpl(); + GameHost host = new GameHost( + inputMangerProxy, + viewManager, + wordGenerator + ); + + host.play(); + } + +} diff --git a/src/main/java/com/wodle/backend/InputManager.java b/src/main/java/com/wodle/backend/InputManager.java new file mode 100644 index 00000000..65c0940a --- /dev/null +++ b/src/main/java/com/wodle/backend/InputManager.java @@ -0,0 +1,7 @@ +package com.wodle.backend; + +import com.wodle.domain.Word; + +public interface InputManager { + Word inputWord(); +} diff --git a/src/main/java/com/wodle/backend/InputManagerImpl.java b/src/main/java/com/wodle/backend/InputManagerImpl.java new file mode 100644 index 00000000..36c7e7a0 --- /dev/null +++ b/src/main/java/com/wodle/backend/InputManagerImpl.java @@ -0,0 +1,19 @@ +package com.wodle.backend; + +import camp.nextstep.edu.missionutils.Console; +import com.wodle.domain.Word; +import java.util.NoSuchElementException; + +public class InputManagerImpl implements InputManager{ + + public Word inputWord() { + try { + String userInput = Console.readLine(); + return new Word(userInput); + } catch (IllegalArgumentException e) { + throw e; + } catch (NoSuchElementException e) { + throw new NoSuchElementException("No such line"); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/wodle/backend/InputMangerProxy.java b/src/main/java/com/wodle/backend/InputMangerProxy.java new file mode 100644 index 00000000..12023e58 --- /dev/null +++ b/src/main/java/com/wodle/backend/InputMangerProxy.java @@ -0,0 +1,24 @@ +package com.wodle.backend; + +import com.wodle.domain.Word; +import com.wodle.ui.ViewManagerImpl; + +public class InputMangerProxy extends InputManagerImpl { + + private final ViewManagerImpl viewManager; + + public InputMangerProxy(ViewManagerImpl viewManager) { + this.viewManager = viewManager; + } + + @Override + public Word inputWord() { + try { + viewManager.printRequestWordInput(); + return super.inputWord(); + } catch (Exception e) { + viewManager.notifyInvalidInputWord(); + return this.inputWord(); + } + } +} diff --git a/src/main/java/com/wodle/backend/WordGenerator.java b/src/main/java/com/wodle/backend/WordGenerator.java new file mode 100644 index 00000000..6c61453b --- /dev/null +++ b/src/main/java/com/wodle/backend/WordGenerator.java @@ -0,0 +1,7 @@ +package com.wodle.backend; + +import com.wodle.domain.AnswerWord; + +public interface WordGenerator { + AnswerWord getTodayWord(); +} diff --git a/src/main/java/com/wodle/backend/WordGeneratorImpl.java b/src/main/java/com/wodle/backend/WordGeneratorImpl.java new file mode 100644 index 00000000..9c0b7c57 --- /dev/null +++ b/src/main/java/com/wodle/backend/WordGeneratorImpl.java @@ -0,0 +1,38 @@ +package com.wodle.backend; + +import com.wodle.domain.AnswerWord; +import com.wodle.utils.FileUtils; +import com.wodle.utils.LocalDateTimeUtils; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class WordGeneratorImpl implements WordGenerator{ + + private static final String FILE_PATH = "words.txt"; + + public AnswerWord getTodayWord() { + try (Stream stream = FileUtils.getInstance().getStreamByFileName(FILE_PATH)) { + List wordList = stream.collect(Collectors.toList()); + long fileMaxLines = wordList.size(); + int wordIndex = getTodayWordIndex(fileMaxLines); + + String todayWord = wordList.get(wordIndex); + return new AnswerWord(todayWord); + } catch (RuntimeException e) { + throw new RuntimeException("can not setting word", e); + } + } + + private int getTodayWordIndex(long totalCount) { + LocalDateTime base = LocalDate.of(2021, 6, 19) + .atStartOfDay(); + LocalDateTime now = LocalDateTime.now(); + + long betweenDays = LocalDateTimeUtils.getInstance().getBetweenDays(base, now); + + return (int) (betweenDays % totalCount); + } +} diff --git a/src/main/java/com/wodle/controller/GameHost.java b/src/main/java/com/wodle/controller/GameHost.java new file mode 100644 index 00000000..12657693 --- /dev/null +++ b/src/main/java/com/wodle/controller/GameHost.java @@ -0,0 +1,22 @@ +package com.wodle.controller; + +import com.wodle.service.GameService; +import com.wodle.backend.InputManagerImpl; +import com.wodle.ui.ViewManager; +import com.wodle.backend.WordGenerator; + +public class GameHost { + + private final GameService gameService; + public GameHost(InputManagerImpl inputManagerProxy, ViewManager viewManager, + WordGenerator wordGenerator) { + this.gameService = new GameService( + wordGenerator, viewManager, inputManagerProxy + ); + } + + public void play() { + gameService.play(); + } + +} diff --git a/src/main/java/com/wodle/domain/AnswerWord.java b/src/main/java/com/wodle/domain/AnswerWord.java new file mode 100644 index 00000000..814f1a2c --- /dev/null +++ b/src/main/java/com/wodle/domain/AnswerWord.java @@ -0,0 +1,45 @@ +package com.wodle.domain; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class AnswerWord extends Word { + + private final boolean[] alphabetExistInfoStore = new boolean[26]; + + public AnswerWord(String word) { + super(word); + Arrays.fill(alphabetExistInfoStore, false); + + char[] words = word.toCharArray(); + + for (char c : words) { + alphabetExistInfoStore[c - 'a'] = true; + } + } + + public Result compare(Word target) { + char[] sourceWordArray = this.getWordArray(); + char[] targetWordArray = target.getWordArray(); + List matchResult = new LinkedList<>(); + + for (int i = 0; i < sourceWordArray.length; i++) { + matchResult.add(match(sourceWordArray, targetWordArray, i)); + } + + return new Result(matchResult); + } + + private TileColor match(char[] source, char[] target, int index) { + if (source[index] == target[index]) { + return TileColor.GREEN; + } + + if (alphabetExistInfoStore[target[index] - 'a']) { + return TileColor.YELLOW; + } + + return TileColor.GREY; + } +} diff --git a/src/main/java/com/wodle/domain/Coins.java b/src/main/java/com/wodle/domain/Coins.java new file mode 100644 index 00000000..dafc61e4 --- /dev/null +++ b/src/main/java/com/wodle/domain/Coins.java @@ -0,0 +1,29 @@ +package com.wodle.domain; + +public class Coins { + + private int coin; + + public Coins(int availableCoin) { + validate(availableCoin); + + this.coin = availableCoin; + } + + public void use() { + int tempCoin = this.coin - 1; + validate(tempCoin); + this.coin = tempCoin; + } + + private void validate(int availableCoin) { + if (availableCoin < 0) { + throw new IllegalArgumentException("Coin can be set under 0"); + } + } + + + public boolean isEmpty() { + return this.coin == 0; + } +} diff --git a/src/main/java/com/wodle/domain/GameMachine.java b/src/main/java/com/wodle/domain/GameMachine.java new file mode 100644 index 00000000..accff388 --- /dev/null +++ b/src/main/java/com/wodle/domain/GameMachine.java @@ -0,0 +1,29 @@ +package com.wodle.domain; + +public class GameMachine { + + private final AnswerWord word; + private boolean gameEnd = false; + + public GameMachine(AnswerWord word) { + this.word = word; + } + + public boolean isGameNotEnd() { + return !gameEnd; + } + + public Result compareWord(Word inputWord) { + Result result = this.word.compare(inputWord); + this.gameEnd = result.isGameEnd(); + return result; + } + + public AnswerWord getWord() { + return word; + } + + public boolean getGameEnd() { + return gameEnd; + } +} \ No newline at end of file diff --git a/src/main/java/com/wodle/domain/Result.java b/src/main/java/com/wodle/domain/Result.java new file mode 100644 index 00000000..96c65159 --- /dev/null +++ b/src/main/java/com/wodle/domain/Result.java @@ -0,0 +1,24 @@ +package com.wodle.domain; + +import com.wodle.domain.TileColor; +import java.util.Collections; +import java.util.List; + +public class Result { + + private final long matchCount; + private final List matchStatus; + + public Result(List matchStatus) { + this.matchStatus = matchStatus; + this.matchCount = matchStatus.stream() + .filter(tileColor -> tileColor == TileColor.GREEN) + .count(); + } + + public boolean isGameEnd() { + return matchCount == matchStatus.size(); + } + + public List getMatchStatus(){ return Collections.unmodifiableList(matchStatus) ;} +} diff --git a/src/main/java/com/wodle/domain/TileColor.java b/src/main/java/com/wodle/domain/TileColor.java new file mode 100644 index 00000000..5ec7c8f9 --- /dev/null +++ b/src/main/java/com/wodle/domain/TileColor.java @@ -0,0 +1,17 @@ +package com.wodle.domain; + +public enum TileColor { + GREEN("\uD83D\uDFE9"), + YELLOW("\uD83D\uDFE8"), + GREY("⬜"); + + private final String print; + + TileColor(String print) { + this.print = print; + } + + public String getPrint() { + return print; + } +} diff --git a/src/main/java/com/wodle/domain/User.java b/src/main/java/com/wodle/domain/User.java new file mode 100644 index 00000000..1c8376ac --- /dev/null +++ b/src/main/java/com/wodle/domain/User.java @@ -0,0 +1,18 @@ +package com.wodle.domain; + + +public class User { + private final Coins coins; + + public User(int availableCoin) { + this.coins = new Coins(availableCoin); + } + + public boolean canPlay() { + return !coins.isEmpty(); + } + + public void pay() { + coins.use(); + } +} diff --git a/src/main/java/com/wodle/domain/Word.java b/src/main/java/com/wodle/domain/Word.java new file mode 100644 index 00000000..6791a8db --- /dev/null +++ b/src/main/java/com/wodle/domain/Word.java @@ -0,0 +1,28 @@ +package com.wodle.domain; + + +import com.wodle.utils.StringUtils; + +public class Word { + + private final String word; + + public Word(String word) { + validate(word); + this.word = word; + } + + private void validate(String word) { + if (!StringUtils.getInstance().matchesFiveSmallAlphabet(word)) { + throw new IllegalArgumentException("user input require 5 small alphabet"); + } + } + + protected char[] getWordArray() { + return word.toCharArray(); + } + + public String getWord() { + return word; + } +} diff --git a/src/main/java/com/wodle/service/GameService.java b/src/main/java/com/wodle/service/GameService.java new file mode 100644 index 00000000..ea4d89ad --- /dev/null +++ b/src/main/java/com/wodle/service/GameService.java @@ -0,0 +1,46 @@ +package com.wodle.service; + +import com.wodle.backend.InputManager; +import com.wodle.backend.WordGenerator; +import com.wodle.domain.AnswerWord; +import com.wodle.domain.GameMachine; +import com.wodle.domain.Result; +import com.wodle.domain.User; +import com.wodle.domain.Word; +import com.wodle.ui.ViewManager; + +public class GameService { + + private static final int START_COIN = 6; + private final WordGenerator wordGenerator; + private final ViewManager viewManager; + private final InputManager inputManagerProxy; + + public GameService(WordGenerator wordGenerator, ViewManager viewManager, + InputManager inputManagerProxy) { + this.wordGenerator = wordGenerator; + this.viewManager = viewManager; + this.inputManagerProxy = inputManagerProxy; + } + + public void play() { + viewManager.printGameStart(); + + GameMachine gameMachine = initGameMachine(); + User user = new User(START_COIN); + + while (gameMachine.isGameNotEnd() && user.canPlay()) { + user.pay(); + Word inputWord = inputManagerProxy.inputWord(); + Result wordCompareResult = gameMachine.compareWord(inputWord); + viewManager.printCompareResult(wordCompareResult); + } + + viewManager.printResult(gameMachine.getGameEnd(), gameMachine.getWord()); + } + + private GameMachine initGameMachine() { + AnswerWord answerWord = wordGenerator.getTodayWord(); + return new GameMachine(answerWord); + } +} diff --git a/src/main/java/com/wodle/ui/ViewManager.java b/src/main/java/com/wodle/ui/ViewManager.java new file mode 100644 index 00000000..36456f74 --- /dev/null +++ b/src/main/java/com/wodle/ui/ViewManager.java @@ -0,0 +1,12 @@ +package com.wodle.ui; + +import com.wodle.domain.Result; +import com.wodle.domain.Word; + +public interface ViewManager { + void printGameStart(); + void printRequestWordInput(); + void notifyInvalidInputWord(); + void printCompareResult(Result woreCompareResult); + void printResult(boolean isGameEnd, Word todayWord); +} diff --git a/src/main/java/com/wodle/ui/ViewManagerImpl.java b/src/main/java/com/wodle/ui/ViewManagerImpl.java new file mode 100644 index 00000000..318215f8 --- /dev/null +++ b/src/main/java/com/wodle/ui/ViewManagerImpl.java @@ -0,0 +1,69 @@ +package com.wodle.ui; + +import com.wodle.domain.Result; +import com.wodle.domain.TileColor; +import com.wodle.domain.Word; +import java.util.LinkedList; +import java.util.List; + +public class ViewManagerImpl implements ViewManager{ + + private static final String FAIL_RESULT_TEXT = "실패 하셨습니다."; + private static final String SUCCESS_RESULT_TEXT = "성공 하셨습니다."; + private static final String TODAY_WORD_PREFIX = "오늘의 단어 "; + private static final String REQUEST_WORD_TEXT = "정답을 입력해 주세요."; + private static final String INPUT_WORD_ERROR_TEXT = "단어는 소문자 5개로 구성된 영단어입니다."; + private static final String GAME_INITIALIZING_TEXT = "WORDLE을 6번 만에 맞춰 보세요.\n" + + "시도의 결과는 타일의 색 변화로 나타납니다."; + + private final List> wordMatchResults; + + public ViewManagerImpl() { + wordMatchResults = new LinkedList<>(); + } + + public void printGameStart() { + System.out.println(GAME_INITIALIZING_TEXT); + } + + public void printRequestWordInput() { + System.out.println(REQUEST_WORD_TEXT); + } + + public void notifyInvalidInputWord() { + System.out.println(INPUT_WORD_ERROR_TEXT); + } + + public void printCompareResult(Result woreCompareResult) { + wordMatchResults.add(woreCompareResult.getMatchStatus()); + + for (List wordMatchResult : wordMatchResults) { + print(wordMatchResult); + System.out.println(); + } + } + + public void printResult(boolean isGameEnd, Word todayWord) { + if (isGameEnd) { + successResultPrint(); + return; + } + + failResultPrint(todayWord); + } + + private void failResultPrint(Word todayWord) { + System.out.println(FAIL_RESULT_TEXT); + System.out.println(TODAY_WORD_PREFIX + todayWord.getWord()); + } + + private void successResultPrint() { + System.out.println(SUCCESS_RESULT_TEXT); + } + + private void print(List curWordMatchResult) { + for (TileColor tileColor : curWordMatchResult) { + System.out.print(tileColor.getPrint()); + } + } +} diff --git a/src/main/java/com/wodle/utils/FileUtils.java b/src/main/java/com/wodle/utils/FileUtils.java new file mode 100644 index 00000000..0a3fe164 --- /dev/null +++ b/src/main/java/com/wodle/utils/FileUtils.java @@ -0,0 +1,36 @@ +package com.wodle.utils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Stream; + +public class FileUtils { + + private static FileUtils fileUtils; + + private FileUtils() { + } + + public static FileUtils getInstance() { + if (fileUtils == null) { + fileUtils = new FileUtils(); + } + + return fileUtils; + } + + public Stream getStreamByFileName(String filePath) { + URL resource = FileUtils.class.getClassLoader().getResource(filePath); + if (resource == null) { + throw new IllegalArgumentException("File not found"); + } + try { + return Files.lines(Path.of(resource.toURI())); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/wodle/utils/LocalDateTimeUtils.java b/src/main/java/com/wodle/utils/LocalDateTimeUtils.java new file mode 100644 index 00000000..36bf5db6 --- /dev/null +++ b/src/main/java/com/wodle/utils/LocalDateTimeUtils.java @@ -0,0 +1,25 @@ +package com.wodle.utils; + +import java.time.Duration; +import java.time.LocalDateTime; + +public class LocalDateTimeUtils { + + private static LocalDateTimeUtils localDateTimeUtils; + + private LocalDateTimeUtils() { + } + + public static LocalDateTimeUtils getInstance() { + if (localDateTimeUtils == null) { + localDateTimeUtils = new LocalDateTimeUtils(); + } + + return localDateTimeUtils; + } + + public long getBetweenDays(LocalDateTime past, LocalDateTime future) { + return Duration.between(past, future) + .toDays(); + } +} diff --git a/src/main/java/com/wodle/utils/StringUtils.java b/src/main/java/com/wodle/utils/StringUtils.java new file mode 100644 index 00000000..c28f3eee --- /dev/null +++ b/src/main/java/com/wodle/utils/StringUtils.java @@ -0,0 +1,27 @@ +package com.wodle.utils; + +import java.util.regex.Pattern; + +public class StringUtils { + + private static StringUtils stringUtils; + + private StringUtils() { + } + + public static StringUtils getInstance() { + if (stringUtils == null) { + stringUtils = new StringUtils(); + } + + return stringUtils; + } + + private static final Pattern smallAlphabetLengthFivePattern = Pattern.compile( + "[a-z]{5}"); + + public boolean matchesFiveSmallAlphabet(String input) { + return smallAlphabetLengthFivePattern.matcher(input) + .matches(); + } +} diff --git a/src/test/java/com/wodle/controller/GameHostTest.java b/src/test/java/com/wodle/controller/GameHostTest.java new file mode 100644 index 00000000..2e86db94 --- /dev/null +++ b/src/test/java/com/wodle/controller/GameHostTest.java @@ -0,0 +1,66 @@ +package com.wodle.controller; + + +import static org.assertj.core.api.Assertions.assertThat; + +import com.wodle.backend.InputMangerProxy; +import com.wodle.ui.ViewManagerImpl; +import com.wodle.backend.WordGeneratorImpl; +import com.wodle.testUtils.FileMockUtils; +import com.wodle.testUtils.LocalDateTimeMockUtils; +import com.wodle.testUtils.SystemInOutUtils; +import java.io.OutputStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class GameHostTest implements FileMockUtils, LocalDateTimeMockUtils, SystemInOutUtils { + + private GameHost gameHost; + + @BeforeEach + public void init() { + fileMockUtilsInit(); + localDateTimeMockUtilsInit(); + + ViewManagerImpl viewManager = new ViewManagerImpl(); + InputMangerProxy inputManagerProxy = new InputMangerProxy(viewManager); + WordGeneratorImpl wordGenerator = new WordGeneratorImpl(); + gameHost = new GameHost( + inputManagerProxy, + viewManager, + wordGenerator + ); + } + + @Test + public void 게임하기정상동작() { + //given + mockingLocalDateTimeUtilsGetBetweenDays(3L); + mockingFileUtilsGetStreamByFileName("aaaaa", "bbbbb", "ccccc", "hello", "eeeee"); + + //when + inputSetting("pwiee\niejdf\nhello"); + OutputStream out = getOutputStream(); + gameHost.play(); + + //then + assertThat(out.toString()).contains( + "성공 하셨습니다.\n"); + } + + @Test + public void 게임하기비정상동작() { + //given + mockingLocalDateTimeUtilsGetBetweenDays(3L); + mockingFileUtilsGetStreamByFileName("aaaaa", "bbbbb", "ccccc", "hello", "eeeee"); + + //when + inputSetting("pwiee\niejdf\neknJe\n32233\nhtioe\nfnsd\neffgr\nffnnh\ncgdeg"); + OutputStream out = getOutputStream(); + gameHost.play(); + + //then + assertThat(out.toString()).contains( + "실패 하셨습니다.\n오늘의 단어 hello\n"); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/domain/CoinsTest.java b/src/test/java/com/wodle/domain/CoinsTest.java new file mode 100644 index 00000000..f393eb19 --- /dev/null +++ b/src/test/java/com/wodle/domain/CoinsTest.java @@ -0,0 +1,72 @@ +package com.wodle.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class CoinsTest { + + @ParameterizedTest + @ValueSource(ints = {0, 1, 2, 3, 4, 5}) + public void NormalCoinInitTest(int availableCoin) { + assertDoesNotThrow( + () -> new Coins(availableCoin) + ); + } + + @ParameterizedTest + @ValueSource(ints = {-1, -2, -3, -4, -5}) + public void AbnormalCoinInitTest(int availableCoin) { + assertThatThrownBy( + () -> new Coins(availableCoin) + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("Coin can be set under 0"); + } + + @Test + public void CoinUseTest() { + //given + Coins coins = new Coins(6); + + //when + coins.use(); + coins.use(); + + //then + assertThat(coins.isEmpty()).isFalse(); + } + + @Test + public void CoinEmptyTest() { + //given + Coins coins = new Coins(2); + + //when + coins.use(); + coins.use(); + + //then + assertThat(coins.isEmpty()).isTrue(); + } + + @Test + public void InvalidCoinUseTest (){ + //given + Coins coins = new Coins(2); + + //when + coins.use(); + coins.use(); + + //then + assertThatThrownBy( + () -> coins.use() + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("Coin can be set under 0"); + } +} diff --git a/src/test/java/com/wodle/domain/GameMachineTest.java b/src/test/java/com/wodle/domain/GameMachineTest.java new file mode 100644 index 00000000..55f7d95c --- /dev/null +++ b/src/test/java/com/wodle/domain/GameMachineTest.java @@ -0,0 +1,41 @@ +package com.wodle.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class GameMachineTest { + + private GameMachine gameMachine; + + @Test + @DisplayName("정답단어 비교시 gameEnd가 true로 셋팅") + public void compareWord_정답() { + //given + AnswerWord answerWord = new AnswerWord("answe"); + gameMachine = new GameMachine(answerWord); + Word inputWord = new Word("answe"); + + //when + Result result = gameMachine.compareWord(inputWord); + + //then + assertThat(gameMachine.getGameEnd()).isTrue(); + } + + @Test + @DisplayName("비정답단어 비교시 gameEnd가 false로 셋팅") + public void compareWord_오답() { + //given + AnswerWord answerWord = new AnswerWord("answe"); + gameMachine = new GameMachine(answerWord); + Word inputWord = new Word("nothi"); + + //when + Result result = gameMachine.compareWord(inputWord); + + //then + assertThat(gameMachine.getGameEnd()).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/domain/ResultTest.java b/src/test/java/com/wodle/domain/ResultTest.java new file mode 100644 index 00000000..2299c1d8 --- /dev/null +++ b/src/test/java/com/wodle/domain/ResultTest.java @@ -0,0 +1,54 @@ +package com.wodle.domain; + +import static com.wodle.domain.TileColor.GREEN; +import static org.assertj.core.api.Assertions.assertThat; + +import com.wodle.domain.Result; +import com.wodle.domain.TileColor; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class ResultTest { + + @Test + public void GameEndTest() { + //given + List matchStatus = Arrays.asList(GREEN, GREEN, GREEN, GREEN, GREEN); + Result result = new Result(matchStatus); + + //when + boolean isGameEnd = result.isGameEnd(); + + assertThat(isGameEnd).isTrue(); + } + + @ParameterizedTest + @CsvSource( + value = { + "GREEN, GREEN, GREEN, GREEN, YELLOW", + "GREEN,GREEN,GREEN,YELLOW,YELLOW", + "GREEN,GREEN,YELLOW,GREY,YELLOW", + "GREEN,GREEN,GREEN,GREEN,GREY", + "GREEN,GREY,YELLOW,GREY,YELLOW" + }, delimiter = ',' + ) + public void GameNotEndTest(String r1, String r2, String r3, String r4, String r5) { + //given + List matchStatus = Arrays.asList( + TileColor.valueOf(r1), + TileColor.valueOf(r2), + TileColor.valueOf(r3), + TileColor.valueOf(r4), + TileColor.valueOf(r5) + ); + Result result = new Result(matchStatus); + + //when + boolean isGameEnd = result.isGameEnd(); + + assertThat(isGameEnd).isFalse(); + } +} diff --git a/src/test/java/com/wodle/domain/WordTest.java b/src/test/java/com/wodle/domain/WordTest.java new file mode 100644 index 00000000..1a607111 --- /dev/null +++ b/src/test/java/com/wodle/domain/WordTest.java @@ -0,0 +1,79 @@ +package com.wodle.domain; + +import static com.wodle.domain.TileColor.GREEN; +import static com.wodle.domain.TileColor.GREY; +import static com.wodle.domain.TileColor.YELLOW; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class WordTest { + + @Test + public void NormalWordCreateTest() { + //given + Word word = new Word("abcde"); + + //when + String wordStr = word.getWord(); + char[] wordArr = word.getWordArray(); + + //then + assertAll( + () -> assertThat(wordStr).isEqualTo("abcde"), + () -> assertThat(wordArr).containsExactly('a', 'b', 'c', 'd', 'e') + ); + } + + @Test + public void AbnormalWordCreateTest() { + assertThatThrownBy( + () -> new Word("abcd2") + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("user input require 5 small alphabet"); + } + + @Test + public void NormalAnswerWordCreateTest() { + //given + AnswerWord word = new AnswerWord("abcde"); + + //when + String wordStr = word.getWord(); + char[] wordArr = word.getWordArray(); + + //then + assertAll( + () -> assertThat(wordStr).isEqualTo("abcde"), + () -> assertThat(wordArr).containsExactly('a', 'b', 'c', 'd', 'e') + ); + } + + @Test + public void AbnormalAnswerWordCreateTest() { + assertThatThrownBy( + () -> new AnswerWord("abcd2") + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("user input require 5 small alphabet"); + } + + @Test + public void AnswerWordCompareTest() { + //given + AnswerWord source = new AnswerWord("abcde"); + Word target = new Word("bdnce"); + + //when + Result result = source.compare(target); + List colors = result.getMatchStatus(); + + //then + assertAll( + () -> assertThat(result.isGameEnd()).isFalse(), + () -> assertThat(colors).containsExactly(YELLOW, YELLOW, GREY, YELLOW, GREEN) + ); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/service/InputManagerTest.java b/src/test/java/com/wodle/service/InputManagerTest.java new file mode 100644 index 00000000..0036be40 --- /dev/null +++ b/src/test/java/com/wodle/service/InputManagerTest.java @@ -0,0 +1,45 @@ +package com.wodle.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.wodle.backend.InputManagerImpl; +import com.wodle.domain.Word; +import com.wodle.testUtils.SystemInOutUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class InputManagerTest implements SystemInOutUtils { + + private InputManagerImpl inputManager; + + @BeforeEach + public void init() { + inputManager = new InputManagerImpl(); + } + + + @Test + public void normalInputManagerTest() { + //given + inputSetting("abcde"); + + //when + Word word = inputManager.inputWord(); + + //then + assertThat(word.getWord()).isEqualTo("abcde"); + } + + @Test + public void abnormalInputManagerTest() { + //given + inputSetting("\nabcde"); + + //when && then + assertThatThrownBy( + () -> inputManager.inputWord() + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("user input require 5 small alphabet"); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/service/InputMangerProxyTest.java b/src/test/java/com/wodle/service/InputMangerProxyTest.java new file mode 100644 index 00000000..eddcef28 --- /dev/null +++ b/src/test/java/com/wodle/service/InputMangerProxyTest.java @@ -0,0 +1,48 @@ +package com.wodle.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import com.wodle.backend.InputMangerProxy; +import com.wodle.domain.Word; +import com.wodle.testUtils.SystemInOutUtils; +import com.wodle.ui.ViewManagerImpl; +import java.io.OutputStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class InputMangerProxyTest implements SystemInOutUtils { + + private InputMangerProxy inputMangerProxy; + + @BeforeEach + public void init() { + inputMangerProxy = new InputMangerProxy(new ViewManagerImpl()); + } + + @ParameterizedTest + @CsvSource( + value = { + "abcde: :abcde:false", + "a8weafa:qwert:qwert:true", + "Abcde:abcde:abcde:true", + "abcdef:abcde:abcde:true" + }, delimiter = ':' + ) + public void inputWordTest(String input1, String input2, String expect, boolean inputInvalid) { + //given + inputSetting(input1 + "\n" + input2); + OutputStream out = getOutputStream(); + + //when + Word word = inputMangerProxy.inputWord(); + + //then + assertAll( + () -> assertThat(word.getWord()).isEqualTo(expect), + () -> assertThat(out.toString().contains("단어는 소문자 5개로 구성된 영단어입니다.")) + .isEqualTo(inputInvalid) + ); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/service/ViewManagerImplTest.java b/src/test/java/com/wodle/service/ViewManagerImplTest.java new file mode 100644 index 00000000..7122513b --- /dev/null +++ b/src/test/java/com/wodle/service/ViewManagerImplTest.java @@ -0,0 +1,94 @@ +package com.wodle.service; + +import static com.wodle.domain.TileColor.GREEN; +import static com.wodle.domain.TileColor.GREY; +import static com.wodle.domain.TileColor.YELLOW; +import static org.assertj.core.api.Assertions.assertThat; + +import com.wodle.domain.AnswerWord; +import com.wodle.domain.Result; +import com.wodle.domain.TileColor; +import com.wodle.testUtils.SystemInOutUtils; +import com.wodle.ui.ViewManagerImpl; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class ViewManagerImplTest implements SystemInOutUtils { + + private ViewManagerImpl viewManager; + + @BeforeEach + public void init() { + viewManager = new ViewManagerImpl(); + } + + + @Test + public void FirstResultViewTest() { + //given + List tileColors = Arrays.asList(GREEN, GREEN, YELLOW, YELLOW, GREY); + Result result = new Result(tileColors); + + //when + OutputStream out = getOutputStream(); + viewManager.printCompareResult(result); + + //then + assertThat(out.toString()).isEqualTo("\uD83D\uDFE9\uD83D\uDFE9\uD83D\uDFE8\uD83D\uDFE8⬜\n"); + } + + @Test + public void SecondResultViewTest() { + //given + List tileColors1 = Arrays.asList(GREEN, GREEN, YELLOW, YELLOW, GREY); + List tileColors2 = Arrays.asList(GREEN, YELLOW, YELLOW, YELLOW, GREY); + Result result1 = new Result(tileColors1); + Result result2 = new Result(tileColors2); + viewManager.printCompareResult(result1); + + //when + OutputStream out = getOutputStream(); + viewManager.printCompareResult(result2); + + //then + assertThat(out.toString()).isEqualTo( + "\uD83D\uDFE9\uD83D\uDFE9\uD83D\uDFE8\uD83D\uDFE8⬜\n\uD83D\uDFE9\uD83D\uDFE8\uD83D\uDFE8\uD83D\uDFE8⬜\n"); + } + + @Test + public void successResultPrintTest() { + //given + boolean isGameEnd = true; + AnswerWord word = new AnswerWord("happy"); + + //when + OutputStream out = getOutputStream(); + viewManager.printResult(isGameEnd, word); + + //then + assertThat(out.toString()).isEqualTo( + "성공 하셨습니다.\n"); + + } + + @ParameterizedTest + @ValueSource(strings = {"happy", "bombs", "honey", "abcde"}) + public void failResultPrintTest(String word) { + //given + boolean isGameEnd = false; + AnswerWord answerWord = new AnswerWord(word); + + //when + OutputStream out = getOutputStream(); + viewManager.printResult(isGameEnd, answerWord); + + //then + assertThat(out.toString()).isEqualTo( + "실패 하셨습니다.\n오늘의 단어 " + answerWord.getWord() + "\n"); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/service/WordGeneratorImplTest.java b/src/test/java/com/wodle/service/WordGeneratorImplTest.java new file mode 100644 index 00000000..b99b2c42 --- /dev/null +++ b/src/test/java/com/wodle/service/WordGeneratorImplTest.java @@ -0,0 +1,53 @@ +package com.wodle.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.wodle.backend.WordGeneratorImpl; +import com.wodle.domain.Word; +import com.wodle.testUtils.FileMockUtils; +import com.wodle.testUtils.LocalDateTimeMockUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class WordGeneratorImplTest implements FileMockUtils, LocalDateTimeMockUtils { + + private WordGeneratorImpl wordGeneratorImpl; + + @BeforeEach + public void init() { + fileMockUtilsInit(); + localDateTimeMockUtilsInit(); + + wordGeneratorImpl = new WordGeneratorImpl(); + } + + + @Test + public void todayWordsTest() { + //given + mockingLocalDateTimeUtilsGetBetweenDays(3L); + mockingFileUtilsGetStreamByFileName("aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee"); + + //when + Word todayWord = wordGeneratorImpl.getTodayWord(); + + //then + assertThat(todayWord.getWord()).isEqualTo("ddddd"); + } + + @Test + public void fileNotFoundTodayWordsTest() { + //given + mockingLocalDateTimeUtilsGetBetweenDays(3L); + mockingFileUtilsGetStreamByFileNameThrow(new IllegalArgumentException("File Not Found")); + + //then + assertThatThrownBy( + () -> wordGeneratorImpl.getTodayWord() + ).isInstanceOf(RuntimeException.class) + .hasMessage("can not setting word"); + + } + +} \ No newline at end of file diff --git a/src/test/java/com/wodle/study/CharArrayTest.java b/src/test/java/com/wodle/study/CharArrayTest.java new file mode 100644 index 00000000..5f60ea19 --- /dev/null +++ b/src/test/java/com/wodle/study/CharArrayTest.java @@ -0,0 +1,22 @@ +package com.wodle.study; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class CharArrayTest { + + @Test + public void CharArraySettingTest() { + //given + String word = "abcd"; + char[] wordChars = word.toCharArray(); + + //when + wordChars[3] = 'a'; + + //then + assertThat(word).isEqualTo("abcd"); + } + +} diff --git a/src/test/java/com/wodle/study/LocalDateStudy.java b/src/test/java/com/wodle/study/LocalDateStudy.java new file mode 100644 index 00000000..34ba7752 --- /dev/null +++ b/src/test/java/com/wodle/study/LocalDateStudy.java @@ -0,0 +1,27 @@ +package com.wodle.study; + +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LocalDateStudy { + + @Test + public void localDateStudy() { + //given + LocalDateTime base = LocalDate.of(2021, 6, 19) + .atStartOfDay(); + LocalDateTime target = LocalDate.of(2021, 6, 21) + .atStartOfDay(); + + //when + long betweenDays = Duration.between(base, target).toDays(); + + //then + Assertions.assertThat(betweenDays).isEqualTo(2); + + } + +} diff --git a/src/test/java/com/wodle/testUtils/FileMockUtils.java b/src/test/java/com/wodle/testUtils/FileMockUtils.java new file mode 100644 index 00000000..7ceddd28 --- /dev/null +++ b/src/test/java/com/wodle/testUtils/FileMockUtils.java @@ -0,0 +1,30 @@ +package com.wodle.testUtils; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +import com.wodle.utils.FileUtils; +import java.util.stream.Stream; +import org.mockito.MockedStatic; + +public interface FileMockUtils { + + FileUtils fileUtils = mock(FileUtils.class); + MockedStatic fileUtilsMockStatic = mockStatic(FileUtils.class); + + default void fileMockUtilsInit() { + fileUtilsMockStatic.when(FileUtils::getInstance).thenReturn(fileUtils); + } + + default void mockingFileUtilsGetStreamByFileName(String... args) { + when(fileUtils.getStreamByFileName(any())) + .thenReturn(Stream.of(args)); + } + + default void mockingFileUtilsGetStreamByFileNameThrow(Throwable e) { + when(fileUtils.getStreamByFileName(any())) + .thenThrow(e); + } +} diff --git a/src/test/java/com/wodle/testUtils/LocalDateTimeMockUtils.java b/src/test/java/com/wodle/testUtils/LocalDateTimeMockUtils.java new file mode 100644 index 00000000..1d98121a --- /dev/null +++ b/src/test/java/com/wodle/testUtils/LocalDateTimeMockUtils.java @@ -0,0 +1,25 @@ +package com.wodle.testUtils; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +import com.wodle.utils.LocalDateTimeUtils; +import org.mockito.MockedStatic; + +public interface LocalDateTimeMockUtils { + + LocalDateTimeUtils localDateTimeUtils = mock(LocalDateTimeUtils.class); + MockedStatic localDateTimeMockUtilsStatic = mockStatic( + LocalDateTimeUtils.class); + + default void localDateTimeMockUtilsInit() { + localDateTimeMockUtilsStatic.when(LocalDateTimeUtils::getInstance) + .thenReturn(localDateTimeUtils); + } + default void mockingLocalDateTimeUtilsGetBetweenDays(long returnValue) { + when(localDateTimeUtils.getBetweenDays(any(), any())) + .thenReturn(returnValue); + } +} diff --git a/src/test/java/com/wodle/testUtils/SystemInOutUtils.java b/src/test/java/com/wodle/testUtils/SystemInOutUtils.java new file mode 100644 index 00000000..3ee4b11c --- /dev/null +++ b/src/test/java/com/wodle/testUtils/SystemInOutUtils.java @@ -0,0 +1,20 @@ +package com.wodle.testUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + +public interface SystemInOutUtils { + + default void inputSetting(String input) { + System.setIn(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8))); + } + + default OutputStream getOutputStream() { + OutputStream out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + return out; + } +} diff --git a/src/test/java/com/wodle/utils/FileUtilsTest.java b/src/test/java/com/wodle/utils/FileUtilsTest.java new file mode 100644 index 00000000..9b8102c9 --- /dev/null +++ b/src/test/java/com/wodle/utils/FileUtilsTest.java @@ -0,0 +1,55 @@ +package com.wodle.utils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class FileUtilsTest { + + private FileUtils fileUtils; + + @BeforeEach + public void init() { + fileUtils = FileUtils.getInstance(); + } + + @Test + public void getStreamByFileNameTest() { + //given + String fileName = "test.txt"; + + //when + Stream streamByFileName = fileUtils.getStreamByFileName(fileName); + List wordList = streamByFileName.collect(Collectors.toList()); + //then + assertAll( + () -> assertThat(wordList) + .hasSize(5) + .containsExactly( + "aaaaa", + "bbbbb", + "ccccc", + "ddddd", + "eeeee" + ) + ); + } + + @Test + public void fileNotFoundTest() { + //given + String fileName = "NON_EXIST_FILE"; + + //when && then + assertThatThrownBy( + () -> fileUtils.getStreamByFileName(fileName) + ).isInstanceOf(IllegalArgumentException.class) + .hasMessage("File not found"); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/utils/LocalDateTimeUtilsTest.java b/src/test/java/com/wodle/utils/LocalDateTimeUtilsTest.java new file mode 100644 index 00000000..5b780c3f --- /dev/null +++ b/src/test/java/com/wodle/utils/LocalDateTimeUtilsTest.java @@ -0,0 +1,54 @@ +package com.wodle.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class LocalDateTimeUtilsTest { + + @Test + public void NormalTimeCompare() { + //given + LocalDateTime past = LocalDate.of(2023, 03, 22) + .atStartOfDay(); + LocalDateTime future = LocalDate.of(2023, 03, 25) + .atStartOfDay(); + + //when + long betweenDays = LocalDateTimeUtils.getInstance().getBetweenDays(past, future); + + //then + assertThat(betweenDays).isEqualTo(3); + } + + @Test + public void AbnormalTimeCompare() { + //given + LocalDateTime future = LocalDate.of(2023, 03, 22) + .atStartOfDay(); + LocalDateTime past = LocalDate.of(2023, 03, 25) + .atStartOfDay(); + + //when + long betweenDays = LocalDateTimeUtils.getInstance().getBetweenDays(past, future); + + //then + assertThat(betweenDays).isEqualTo(-3); + } + + @Test + public void nonStartOfDayTest() { + //given + LocalDateTime past = LocalDateTime.of(2023, 03, 26, 5, 3); + LocalDateTime future = LocalDateTime.of(2023, 03, 27, 5, 3); + + //when + long betweenDays = LocalDateTimeUtils.getInstance().getBetweenDays(past, future); + + //then + assertThat(betweenDays).isEqualTo(1); + } +} \ No newline at end of file diff --git a/src/test/java/com/wodle/utils/StringUtilsTest.java b/src/test/java/com/wodle/utils/StringUtilsTest.java new file mode 100644 index 00000000..7e780475 --- /dev/null +++ b/src/test/java/com/wodle/utils/StringUtilsTest.java @@ -0,0 +1,29 @@ +package com.wodle.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class StringUtilsTest { + + @ParameterizedTest + @ValueSource(strings = {"aaaaa", "bbbbb", "ccccc", "ddddd"}) + public void normalTest(String source) { + //when + boolean result = StringUtils.getInstance().matchesFiveSmallAlphabet(source); + + //then + assertThat(result).isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = {"aaaa", "bbb", "cc", "d", "Aaaaa", "1aaaa", "ㅁaaaa"}) + public void abNormalTest(String source) { + //when + boolean result = StringUtils.getInstance().matchesFiveSmallAlphabet(source); + + //then + assertThat(result).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/resources/test.txt b/src/test/resources/test.txt new file mode 100644 index 00000000..903635d0 --- /dev/null +++ b/src/test/resources/test.txt @@ -0,0 +1,5 @@ +aaaaa +bbbbb +ccccc +ddddd +eeeee \ No newline at end of file