diff --git a/README-HS.md b/README-HS.md new file mode 100644 index 0000000..6b66e26 --- /dev/null +++ b/README-HS.md @@ -0,0 +1,72 @@ +## 요구사항 +1. 좌표값을 두 개 입력한 경우 두 점을 잇는 직선으로 가정 +2. 좌표와 좌표값 사이 '-' 문자로 구분 +3. 좌표값을 네 개 입력한 경우 네 점을 연결하는 사각형으로 가정 + - 네 점이 뒤틀어진 사다리꼴이나 마름모는 제외하고 직사각형만 허용하도록 검사 + - 사각형인 경우 사각형 넓이를 계산해서 출력 + + +## 프로그래밍 요구사항 +1. depth 2를 넘지 않도록 구현 (1까지만 허용) +2. 3항 연산자 금지 +3. else 예약어 금지 +4. switch/case 금지 +5. 메소드 10줄 넘어가지 않도록 구현 +6. 일급 컬렉션 + + +## 실행 결과 +``` +좌표를 입력하세요. +(10,10)-(22,10)-(22,18)-(10,18) + + +24| + | +22| ● ● + | +20| + | +18| + | +16| + | +14| + | +12| + | +10| ● ● + | + 8| + | + 6| + | + 4| + | + 2| + | + +―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― + 0 2 4 6 8 10 12 14 16 18 20 22 24 + +사각형의 넓이는 96 +``` + +## 힌트 +1. 사각형 면적은 width * height 방식으로 계산할 수 있다. +2. Point 라는 객체를 추가해 x, y 좌표를 관리하도록 한다. + +- 직사각형 좌표 +(2,3)-(2,10)-(7,3)-(7,10) +(4,6)-(4,15)-(12,6)-(12,15) + +- 직사각형이 아닌 좌표 +(3,5)-(7,14)-(15,18)-(21,3) +(2,8)-(9,17)-(18,6)-(23,11) + +- 마름모 +(12,6)-(18,18)-(6,18)-(0,6) +(6,12)-(12,18)-(18,12)-(12,6) + +- 선 +(10,10)-(14,15) +두 점 사이 거리는 6.403124 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..d2880ba 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/CoordinateMain.java b/src/main/java/CoordinateMain.java new file mode 100644 index 0000000..4120961 --- /dev/null +++ b/src/main/java/CoordinateMain.java @@ -0,0 +1,20 @@ +import io.InputScanner; +import io.ResultView; +import model.Calculator; +import model.Points; + +public class CoordinateMain { + public static void main(String[] args) { + InputScanner scanner = new InputScanner(); + Points points = scanner.input(); + + Calculator calculator = new Calculator(points); + double result = calculator.calculate(); + + ResultView resultView = new ResultView(points, result); + resultView.print(); + + } + + +} diff --git a/src/main/java/io/InputScanner.java b/src/main/java/io/InputScanner.java new file mode 100644 index 0000000..5eaac0b --- /dev/null +++ b/src/main/java/io/InputScanner.java @@ -0,0 +1,59 @@ +package io; + +import messages.ErrorMessages; +import model.Points; +import model.Rectangle; + +import java.util.Scanner; + +public class InputScanner { + private final Scanner scanner; + + public InputScanner(){ + scanner = new Scanner(System.in); + } + + public Points input(){ + System.out.println("좌표를 입력하세요."); + return validateInput(scanner.nextLine()); + } + + public Points validateInput(String input){ + Points points; + + try{ + checkMatchPattern(input); + points = Points.fromString(input); + checkRectangleShapes(points); + + } catch(IllegalArgumentException ex){ + System.out.println(ex.getMessage()); + return input(); + } + + return points; + } + + public void checkMatchPattern(String input){ + if(!isMatchTwoPoints(input) && !isMatchFourPoints(input)){ + throw new IllegalArgumentException(ErrorMessages.INVALID_PATTERN); + } + } + + public boolean isMatchTwoPoints(String input) { + return input.matches("\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)"); + } + + + public boolean isMatchFourPoints(String input) { + return input.matches("\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)"); + } + + public void checkRectangleShapes(Points points){ + if (points.isFourPoints()){ + Rectangle rectangle = new Rectangle(points); + rectangle.validateRectangle(); + } + } + +} diff --git a/src/main/java/io/ResultView.java b/src/main/java/io/ResultView.java new file mode 100644 index 0000000..46a9dc7 --- /dev/null +++ b/src/main/java/io/ResultView.java @@ -0,0 +1,32 @@ +package io; + +import model.Graph; +import model.Points; + +public class ResultView { + + private Points points; + private Graph graph; + private double result; + + public ResultView(Points points, double result){ + this.points = points; + this.graph = Graph.from(points); + this.result = result; + } + + public void print(){ + StringBuilder[] graphDrawing = graph.draw(); + + for (StringBuilder drawing : graphDrawing){ + System.out.println(drawing.toString()); + } + + if (points.isTwoPoints()){ + System.out.println("두 점 사이 거리는 " + result); + } + + System.out.println("사각형의 넓이는 " + result); + } + +} diff --git a/src/main/java/messages/ErrorMessages.java b/src/main/java/messages/ErrorMessages.java new file mode 100644 index 0000000..eb3bf96 --- /dev/null +++ b/src/main/java/messages/ErrorMessages.java @@ -0,0 +1,8 @@ +package messages; + +public class ErrorMessages { + public static final String INVALID_PATTERN = "입력이 올바르지 않습니다. 다시 입력해주세요."; + public static final String INVALID_NUMBER = "숫자가 아닌 값은 입력할 수 없습니다. 다시 입력해주세요."; + public static final String INVALID_RECTANGLE = "직사각형이 아닌 좌표는 입력할 수 없습니다. 다시 입력해주세요."; + public static final String INVALID_RANGE = "좌표값은 0부터 24까지만 입력 가능합니다. 다시 입력해주세요."; +} diff --git a/src/main/java/model/Calculator.java b/src/main/java/model/Calculator.java new file mode 100644 index 0000000..85abe02 --- /dev/null +++ b/src/main/java/model/Calculator.java @@ -0,0 +1,23 @@ +package model; + +public class Calculator { + + private Points points; + + public Calculator(Points points){ + this.points = points; + } + + public double calculate(){ + if (points.isTwoPoints()){ + Line line = new Line(points); + return line.calculateLength(); + } + + Rectangle rectangle = new Rectangle(points); + return rectangle.calculateArea(); + } + + + +} diff --git a/src/main/java/model/Graph.java b/src/main/java/model/Graph.java new file mode 100644 index 0000000..4ebe400 --- /dev/null +++ b/src/main/java/model/Graph.java @@ -0,0 +1,77 @@ +package model; + +public class Graph { + private final static int TOTAL_X_SIZE = 48; + private final static int TOTAL_Y_SIZE = 26; + private final static int X_LINE = 24; + private final static int X_NUMBER_LINE = 25; + private final static int MAX_NUMBER = 24; + + private Points points; + private StringBuilder[] graph; + + public Graph(Points points){ + this.points = points; + initGraph(); + } + + public void initGraph(){ + graph = new StringBuilder[TOTAL_Y_SIZE]; + + for (int i=0; i<=X_LINE; i++){ + graph[i] = new StringBuilder(" ".repeat(TOTAL_X_SIZE)); + } + } + + public static Graph from(Points points){ + return new Graph(points); + } + + public StringBuilder[] draw(){ + drawY(); + drawX(); + points.drawPoints(graph); + + return graph; + } + + + public void drawY(){ + int yNum = MAX_NUMBER; + + for(int i=0; i lines; + + public Lines(Points points){ + this.points = points; + this.lines = createAllLines(); + } + + public List createAllLines(){ + List lineList = new ArrayList<>(); + + for (int i=0; i lineList, int i){ + for (int j=i+1; j allSortedLinesLength(){ + return lines.stream() + .map(Line::calculateLength) + .sorted() + .toList(); + } +} diff --git a/src/main/java/model/Point.java b/src/main/java/model/Point.java new file mode 100644 index 0000000..8bbd2bc --- /dev/null +++ b/src/main/java/model/Point.java @@ -0,0 +1,62 @@ +package model; + +import messages.ErrorMessages; + +import java.util.Objects; + +public class Point { + private static final int MAX_COORDINATE = 24; + private static final int MIN_COORDINATE = 0; + private static final int X_PADDING = 3; + + private int x; + private int y; + + public Point(){} + + public Point(int x, int y){ + this.x = x; + this.y = y; + validateRange(); + } + + public static Point of(int x, int y){ + return new Point(x, y); + } + + + public void validateRange(){ + if (!isCorrectRange(x) || !isCorrectRange(y)){ + throw new IllegalArgumentException(ErrorMessages.INVALID_RANGE); + } + } + + public boolean isCorrectRange(int value){ + return value <= MAX_COORDINATE && value >= MIN_COORDINATE; + } + + public double minusX(Point other) { + return x - other.x; + } + + public double minusY(Point other) { + return y - other.y; + } + + public void drawPoint(StringBuilder[] graph){ + graph[MAX_COORDINATE - y].setCharAt(x * X_PADDING, '●'); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Point point = (Point) o; + return x == point.x && y == point.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } +} diff --git a/src/main/java/model/Points.java b/src/main/java/model/Points.java new file mode 100644 index 0000000..5be3e8a --- /dev/null +++ b/src/main/java/model/Points.java @@ -0,0 +1,62 @@ +package model; + +import util.CoordinateUtils; + +import java.util.ArrayList; +import java.util.List; + +public class Points { + private List points; + + public Points(){ + this.points = new ArrayList<>(); + } + + public Points(Point point1, Point point2){ + this.points = new ArrayList<>(List.of(point1, point2)); + } + + public static Points from(Point point1, Point point2){ + return new Points(point1, point2); + } + + public static Points fromString(String input){ + List numbers = CoordinateUtils.splitStringToInteger(input); + + Points points = new Points(); + for(int i=0; i linesLength; + + public Rectangle(Points points){ + this.lines = new Lines(points); + this.linesLength = lines.allSortedLinesLength(); + } + + public double calculateArea(){ + return linesLength.get(WIDTH_INDEX) * linesLength.get(HEIGHT_INDEX); + } + + public void validateRectangle(){ + if (!isRectangle()){ + throw new IllegalArgumentException(ErrorMessages.INVALID_RECTANGLE); + } + } + + public boolean isRectangle(){ + return linesLength.get(0).equals(linesLength.get(1)) + && linesLength.get(2).equals(linesLength.get(3)) + && linesLength.get(4).equals(linesLength.get(5)) + && !linesLength.get(0).equals(linesLength.get(2)); + } + +} diff --git a/src/main/java/util/CoordinateUtils.java b/src/main/java/util/CoordinateUtils.java new file mode 100644 index 0000000..3b03861 --- /dev/null +++ b/src/main/java/util/CoordinateUtils.java @@ -0,0 +1,27 @@ +package util; + +import messages.ErrorMessages; + +import java.util.List; +import java.util.regex.MatchResult; +import java.util.regex.Pattern; + +public class CoordinateUtils { + + public static Integer parseInteger(String str){ + try{ + return Integer.parseInt(str); + } catch (IllegalArgumentException ex){ + throw new IllegalArgumentException(ErrorMessages.INVALID_NUMBER); + } + } + + public static List splitStringToInteger(String str){ + return Pattern.compile("\\d+") + .matcher(str) + .results() + .map(MatchResult::group) + .map(CoordinateUtils::parseInteger) + .toList(); + } +} diff --git a/src/test/java/io/InputScannerTest.java b/src/test/java/io/InputScannerTest.java new file mode 100644 index 0000000..36e3616 --- /dev/null +++ b/src/test/java/io/InputScannerTest.java @@ -0,0 +1,187 @@ +package io; + +import messages.ErrorMessages; +import model.Point; +import model.Points; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class InputScannerTest { + + private InputScanner scanner; + + @BeforeEach + void setUp(){ + scanner = new InputScanner(); + } + + @Test + @DisplayName("입력값 유효성 검사 - 직선") + void validateInput_line(){ + // given, when + Points response = scanner.validateInput("(10,10)-(22,10)"); + + // then + assertThat(response.size()).isEqualTo(2); + assertThat(response.getPoint(0)).isEqualTo(Point.of(10, 10)); + assertThat(response.getPoint(1)).isEqualTo(Point.of(22, 10)); + } + + + @Test + @DisplayName("입력값 유효성 검사 - 직사각형") + void validateInput_rectangle(){ + // given, when + Points response = scanner.validateInput("(10,10)-(22,10)-(22,18)-(10,18)"); + + // then + assertThat(response.size()).isEqualTo(4); + assertThat(response.getPoint(0)).isEqualTo(Point.of(10, 10)); + assertThat(response.getPoint(1)).isEqualTo(Point.of(22, 10)); + assertThat(response.getPoint(2)).isEqualTo(Point.of(22, 18)); + assertThat(response.getPoint(3)).isEqualTo(Point.of(10, 18)); + } + + @Test + @DisplayName("입력값 패턴 확인 - 직선") + void checkMatchPattern_line(){ + // given, when, then + assertDoesNotThrow(() -> scanner.checkMatchPattern("(10,10)-(22,10)")); + } + + @Test + @DisplayName("입력값 패턴 확인 - 사각형") + void checkMatchPattern_rectangle(){ + // given, when, then + assertDoesNotThrow(() -> scanner.checkMatchPattern("(10,10)-(22,10)-(22,18)-(10,18)")); + } + + + @Test + @DisplayName("입력값 패턴 맞지 않아 예외 발생 - 직선") + void misMatchPattern_line(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.checkMatchPattern("(10,10)-(22,")); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_PATTERN); + } + + @Test + @DisplayName("입력값 패턴 맞지 않아 예외 발생 - 사각형") + void misMatchPattern_rectangle(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.checkMatchPattern("(10,10)-(22,10)-(22,18)-(10,18)-")); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_PATTERN); + } + + @Test + @DisplayName("직선 패턴 확인 시 true 반환") + void isMatchTwoPoints_true(){ + // given, when + boolean response = scanner.isMatchTwoPoints("(10,10)-(22,10)"); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("직선 패턴 확인 시 false 반환") + void isMatchTwoPoints_false(){ + // given, when + boolean response = scanner.isMatchTwoPoints("(10,10)-(22,10"); + + // then + assertThat(response).isFalse(); + } + + @Test + @DisplayName("직사각형 패턴 확인 시 true 반환") + void isMatchFourPoints_true(){ + // given, when + boolean response = scanner.isMatchFourPoints("(10,10)-(22,10)-(22,18)-(10,18)"); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("직사각형 패턴 확인 시 false 반환") + void isMatchFourPoints_false(){ + // given, when + boolean response = scanner.isMatchFourPoints("(10,10)-(22,10)-(22,18)-(10,1"); + + // then + assertThat(response).isFalse(); + } + + @Test + @DisplayName("직사각형 유효성 검사") + void checkRectangleShapes(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + // when, then + assertDoesNotThrow(() -> scanner.checkRectangleShapes(points)); + } + + + @Test + @DisplayName("직사각형이 아닌 경우 유효성 검사 실행 안함") + void checkRectangleShapes_line(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + + // when, then + assertDoesNotThrow(() -> scanner.checkRectangleShapes(points)); + } + + @Test + @DisplayName("직사각형 유효성 검사 시 마름모로 예외 발생") + void checkRectangleShapes_diamond(){ + // given + Points points = new Points(); + points.addPoint(12, 6); + points.addPoint(18, 18); + points.addPoint(6, 18); + points.addPoint(0, 6); + + // when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.checkRectangleShapes(points)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RECTANGLE); + + } + + @Test + @DisplayName("직사각형 유효성 검사 시 직사각형이 아닌 도형으로 예외 발생") + void checkRectangleShapes_notRectangle(){ + // given + Points points = new Points(); + points.addPoint(3,5); + points.addPoint(7,14); + points.addPoint(15,18); + points.addPoint(21,3); + + // when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.checkRectangleShapes(points)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RECTANGLE); + + } + +} \ No newline at end of file diff --git a/src/test/java/model/CalculatorTest.java b/src/test/java/model/CalculatorTest.java new file mode 100644 index 0000000..d041959 --- /dev/null +++ b/src/test/java/model/CalculatorTest.java @@ -0,0 +1,46 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CalculatorTest { + + @Test + @DisplayName("직선 길이 구하기") + void calculate_line(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(14, 15); + + Calculator calculator = new Calculator(points); + + // when + double response = calculator.calculate(); + + // then + assertThat(response).isEqualTo(6.4031242374328485); + } + + @Test + @DisplayName("직사각형 넓이 구하기") + void calculate_rectangle(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Calculator calculator = new Calculator(points); + + // when + double response = calculator.calculate(); + + // then + assertThat(response).isEqualTo(96); + } + +} \ No newline at end of file diff --git a/src/test/java/model/LineTest.java b/src/test/java/model/LineTest.java new file mode 100644 index 0000000..ee5ab8e --- /dev/null +++ b/src/test/java/model/LineTest.java @@ -0,0 +1,61 @@ +package model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LineTest { + + private Line line; + + @BeforeEach + void setUp(){ + line = Line.of(Point.of(10, 10), Point.of(14, 15)); + } + + + @Test + @DisplayName("길이 계산") + void calculateLength(){ + // given, when + double response = line.calculateLength(); + + // then + assertThat(response).isEqualTo(6.4031242374328485); + } + + @Test + @DisplayName("x 좌표 뺄셈") + void minusX(){ + // given, when + double response = line.minusX(); + + // then + assertThat(response).isEqualTo(-4); + } + + @Test + @DisplayName("y 좌표 뺄셈") + void minusY(){ + // given, when + double response = line.minusY(); + + // then + assertThat(response).isEqualTo(-5); + } + + @Test + @DisplayName("2배수") + void powOfTwo(){ + // given, when + double response = line.powOfTwo(4); + + // then + assertThat(response).isEqualTo(16); + } + + +} \ No newline at end of file diff --git a/src/test/java/model/LinesTest.java b/src/test/java/model/LinesTest.java new file mode 100644 index 0000000..f6e954f --- /dev/null +++ b/src/test/java/model/LinesTest.java @@ -0,0 +1,89 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LinesTest { + + + @Test + @DisplayName("Points 객체(size 4) 이용해 가능한 Line 리스트 생성") + void createAllLines1(){ + // given + Points points = new Points(); + for (int i=0; i<4; i++){ + points.addPoint(i, i+1); + } + + Lines lines = new Lines(points); + + // when + List response = lines.createAllLines(); + + // then + assertThat(response.size()).isEqualTo(6); + } + + @Test + @DisplayName("Points 객체(size 2) 이용해 가능한 Line 리스트 생성") + void createAllLines2(){ + // given + Points points = new Points(); + for (int i=0; i<2; i++){ + points.addPoint(i, i+1); + } + + Lines lines = new Lines(points); + + // when + List response = lines.createAllLines(); + + // then + assertThat(response.size()).isEqualTo(1); + } + + @Test + @DisplayName("Points 객체를 이용해 가능한 모든 Line 조합 생성") + void allLineForPoints(){ + // given + Points points = new Points(); + for (int i=0; i<4; i++){ + points.addPoint(i, i+1); + } + + Lines lines = new Lines(points); + List lineList = new ArrayList<>(); + + // when + lines.allLineForPoints(points, lineList, 2); + + // then + assertThat(lineList.size()).isEqualTo(1); + } + + @Test + @DisplayName("모든 Line 길이 계산해서 오름차순으로 정렬") + void allSortedLinesLength(){ + // given + Points points = new Points(); + for (int i=0; i<4; i++){ + points.addPoint(i, i+1); + } + + Lines lines = new Lines(points); + + // when + List response = lines.allSortedLinesLength(); + + // then + assertThat(response.size()).isEqualTo(6); + assertThat(response.get(1)).isGreaterThanOrEqualTo(response.get(0)); + } + +} \ No newline at end of file diff --git a/src/test/java/model/PointTest.java b/src/test/java/model/PointTest.java new file mode 100644 index 0000000..86e4950 --- /dev/null +++ b/src/test/java/model/PointTest.java @@ -0,0 +1,116 @@ +package model; + +import messages.ErrorMessages; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class PointTest { + + @Test + @DisplayName("x, y 좌표 범위 유효성 체크") + void validateRange(){ + // given + Point point = new Point(24, 0); + + // when, then + assertDoesNotThrow(point::validateRange); + + } + + @Test + @DisplayName("x, y 좌표 범위 유효성 체크 시 x 좌표 예외 발생") + void InvalidateXRange(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> new Point(25, 0)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE); + } + + @Test + @DisplayName("x, y 좌표 범위 유효성 체크 시 Y 좌표 예외 발생") + void InvalidateYRange(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> new Point(24, -1)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE); + } + + @Test + @DisplayName("범위 체크 시 true 반환") + void isCorrectRange_true(){ + // given + Point point = new Point(); + + // when + boolean response = point.isCorrectRange(24); + + // then + assertThat(response).isTrue(); + + } + + @Test + @DisplayName("범위 체크 시 false 반환") + void isCorrectRange_false(){ + // given + Point point = new Point(); + + // when + boolean response = point.isCorrectRange(25); + + // then + assertThat(response).isFalse(); + } + + @Test + @DisplayName("x 좌표 뺄셈") + void minusX(){ + // given + Point point1 = Point.of(24, 0); + Point point2 = Point.of(0, 24); + + // when + double response = point1.minusX(point2); + + // then + assertThat(response).isEqualTo(24); + } + + @Test + @DisplayName("y 좌표 뺄셈") + void minusY(){ + // given + Point point1 = Point.of(24, 0); + Point point2 = Point.of(0, 24); + + // when + double response = point1.minusY(point2); + + // then + assertThat(response).isEqualTo(-24); + } + + @Test + @DisplayName("좌표 그리기") + void drawPoint(){ + // given + StringBuilder[] graph = new StringBuilder[1]; + graph[0] = new StringBuilder().append(" "); + + Point point = Point.of(0, 24); + + // when + point.drawPoint(graph); + + // then + assertThat(graph[0]).contains("●"); + + + } + +} \ No newline at end of file diff --git a/src/test/java/model/PointsTest.java b/src/test/java/model/PointsTest.java new file mode 100644 index 0000000..43e7b82 --- /dev/null +++ b/src/test/java/model/PointsTest.java @@ -0,0 +1,125 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class PointsTest { + + @Test + @DisplayName("문자열로 Points 객체 생성") + void fromString(){ + // given, when + Points response = Points.fromString("(10,10)-(22,10)-(22,18)-(10,18)"); + + // then + assertThat(response.getPoint(0)).isEqualTo(Point.of(10, 10)); + assertThat(response.getPoint(1)).isEqualTo(Point.of(22, 10)); + assertThat(response.getPoint(2)).isEqualTo(Point.of(22, 18)); + assertThat(response.getPoint(3)).isEqualTo(Point.of(10, 18)); + } + + @Test + @DisplayName("Points 객체 추가") + void addPoint(){ + // given + Points points = new Points(); + + // when + points.addPoint(24, 0); + + // then + assertThat(points.getPoint(0)).isEqualTo(Point.of(24, 0)); + + } + + @Test + @DisplayName("Points 객체 사이즈 2 인지 확인해 true 반환") + void isTwoPoints_true(){ + // given + Points points = Points.from(Point.of(24, 0), Point.of(0, 24)); + + // when + boolean response = points.isTwoPoints(); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("Points 객체 사이즈 2 인지 확인해 false 반환") + void isTwoPoints_false(){ + // given + Points points = new Points(); + + // when + boolean response = points.isTwoPoints(); + + // then + assertThat(response).isFalse(); + } + + @Test + @DisplayName("Points 객체 사이즈 4 인지 확인해 true 반환") + void isFourPoints_true(){ + // given + Points points = new Points(); + for (int i=0; i<4; i++){ + points.addPoint(i, i+1); + } + + // when + boolean response = points.isFourPoints(); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("Points 객체 사이즈 4 인지 확인해 false 반환") + void isFourPoints_false(){ + // given + Points points = new Points(); + + // when + boolean response = points.isFourPoints(); + + // then + assertThat(response).isFalse(); + } + + @Test + @DisplayName("Points 객체 사이즈 반환") + void size(){ + // given + Points points = new Points(); + + // when + int response = points.size(); + + // then + assertThat(response).isEqualTo(0); + } + + @Test + @DisplayName("Points 객체 그래프 그리기") + void drawPoints(){ + // given + StringBuilder[] graph = new StringBuilder[2]; + for (int i=0; i<2; i++){ + graph[i] = new StringBuilder().append(" "); + } + + Points points = new Points(Point.of(0, 24), Point.of(1, 23)); + + // when + points.drawPoints(graph); + + // then + assertThat(graph[0]).contains("●"); + assertThat(graph[1]).contains("●"); + + } +} \ No newline at end of file diff --git a/src/test/java/model/RectangleTest.java b/src/test/java/model/RectangleTest.java new file mode 100644 index 0000000..d7c764f --- /dev/null +++ b/src/test/java/model/RectangleTest.java @@ -0,0 +1,106 @@ +package model; + +import messages.ErrorMessages; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class RectangleTest { + + @Test + @DisplayName("넓이 계산") + void calculateArea(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Rectangle rectangle = new Rectangle(points); + + // when + double response = rectangle.calculateArea(); + + // then + assertThat(response).isEqualTo(96.0); + } + + @Test + @DisplayName("직사각형 유효성 검사") + void validateRectangle(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Rectangle rectangle = new Rectangle(points); + + // when + assertDoesNotThrow(rectangle::validateRectangle); + } + + @Test + @DisplayName("직사각형 유효성 검사로 예외 발생") + void invalidateRectangle(){ + // given + Points points = new Points(); + points.addPoint(0, 0); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Rectangle rectangle = new Rectangle(points); + + // when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, rectangle::validateRectangle); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RECTANGLE); + } + + @Test + @DisplayName("직사각형 여부 true 반환") + void isRectangle_true(){ + // given + Points points = new Points(); + points.addPoint(10, 10); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Rectangle rectangle = new Rectangle(points); + + // when + boolean response = rectangle.isRectangle(); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("직사각형 여부 false 반환") + void isRectangle_false(){ + // given + Points points = new Points(); + points.addPoint(0, 0); + points.addPoint(22, 10); + points.addPoint(22, 18); + points.addPoint(10, 18); + + Rectangle rectangle = new Rectangle(points); + + // when + boolean response = rectangle.isRectangle(); + + // then + assertThat(response).isFalse(); + } + + + +} \ No newline at end of file diff --git a/src/test/java/util/CoordinateUtilsTest.java b/src/test/java/util/CoordinateUtilsTest.java new file mode 100644 index 0000000..64b9bbf --- /dev/null +++ b/src/test/java/util/CoordinateUtilsTest.java @@ -0,0 +1,72 @@ +package util; + +import messages.ErrorMessages; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class CoordinateUtilsTest { + + @Test + @DisplayName("문자열 숫자로 변환") + void parseInteger(){ + // given, when + Integer response = CoordinateUtils.parseInteger("13"); + + // then + assertThat(response).isEqualTo(13); + } + + @Test + @DisplayName("문자열 숫자로 변환 시 예외 발생") + void parseIntegerNotNumber(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> CoordinateUtils.parseInteger("문자열")); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_NUMBER); + } + + @Test + @DisplayName("문자열 숫자 리스트로 변환 - 직선") + void splitStringToInteger1(){ + // given, when + List response = CoordinateUtils.splitStringToInteger("(10,10)-(22,10)"); + + // then + assertThat(response.size()).isEqualTo(4); + assertThat(response.get(0)).isEqualTo(10); + assertThat(response.get(1)).isEqualTo(10); + assertThat(response.get(2)).isEqualTo(22); + assertThat(response.get(3)).isEqualTo(10); + } + + @Test + @DisplayName("문자열 숫자 리스트로 변환 - 직사각형") + void splitStringToInteger2(){ + // given, when + List response = CoordinateUtils.splitStringToInteger("(10,10)-(22,10)-(22,18)-(10,18)"); + + // then + assertThat(response.size()).isEqualTo(8); + assertThat(response.get(0)).isEqualTo(10); + assertThat(response.get(1)).isEqualTo(10); + assertThat(response.get(2)).isEqualTo(22); + assertThat(response.get(3)).isEqualTo(10); + } + + @Test + @DisplayName("문자열 숫자 리스트로 변환 시 숫자가 아닌 값으로 인해 리스트 사이즈 0") + void splitStringToIntegerNotNumber(){ + // given, when + List response = CoordinateUtils.splitStringToInteger("문자열"); + + // then + assertThat(response.size()).isEqualTo(0); + } + +} \ No newline at end of file