diff --git a/build.gradle b/build.gradle index a0a012f579..59499314c9 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,8 @@ repositories { } dependencies { + implementation 'org.projectlombok:lombok:1.18.26' + annotationProcessor 'org.projectlombok:lombok:1.18.26' testImplementation 'org.assertj:assertj-core:3.22.0' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' } diff --git a/src/main/java/nextstep/fp/Lambda.java b/src/main/java/nextstep/fp/Lambda.java index bd68fe1ce6..fb2b88ea63 100644 --- a/src/main/java/nextstep/fp/Lambda.java +++ b/src/main/java/nextstep/fp/Lambda.java @@ -26,31 +26,10 @@ public void run() { }).start(); } - public static int sumAll(List numbers) { - int total = 0; - for (int number : numbers) { - total += number; - } - return total; - } - - public static int sumAllEven(List numbers) { - int total = 0; - for (int number : numbers) { - if (number % 2 == 0) { - total += number; - } - } - return total; - } - - public static int sumAllOverThree(List numbers) { - int total = 0; - for (int number : numbers) { - if (number > 3) { - total += number; - } - } - return total; + public static int sumAll(List numbers, SumStrategy sumStrategy) { + return numbers.stream() + .filter(sumStrategy::option) + .mapToInt(value -> value) + .sum(); } } diff --git a/src/main/java/nextstep/fp/StreamStudy.java b/src/main/java/nextstep/fp/StreamStudy.java index b446983a02..67e7c8ac67 100644 --- a/src/main/java/nextstep/fp/StreamStudy.java +++ b/src/main/java/nextstep/fp/StreamStudy.java @@ -5,6 +5,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -15,11 +16,9 @@ public static long countWords() throws IOException { .get("src/main/resources/fp/war-and-peace.txt")), StandardCharsets.UTF_8); List words = Arrays.asList(contents.split("[\\P{L}]+")); - long count = 0; - for (String w : words) { - if (w.length() > 12) count++; - } - return count; + return words.stream() + .filter(w -> w.length() > 12) + .count(); } public static void printLongestWordTop100() throws IOException { @@ -27,7 +26,11 @@ public static void printLongestWordTop100() throws IOException { .get("src/main/resources/fp/war-and-peace.txt")), StandardCharsets.UTF_8); List words = Arrays.asList(contents.split("[\\P{L}]+")); - // TODO 이 부분에 구현한다. + words.stream() + .filter(w -> w.length() > 12) // 단어 길이 12 이상 + .sorted((o1, o2) -> o2.length() - o1.length()) // 긴 순서 + .distinct() + .forEach(s -> System.out.println(s.toLowerCase())); } public static List doubleNumbers(List numbers) { @@ -39,6 +42,9 @@ public static long sumAll(List numbers) { } public static long sumOverThreeAndDouble(List numbers) { - return 0; + return numbers.stream() + .filter(i -> i > 3) + .map(i -> 2 * i) + .reduce(0, (x, y) -> x + y); } } \ No newline at end of file diff --git a/src/main/java/nextstep/fp/SumStrategy.java b/src/main/java/nextstep/fp/SumStrategy.java new file mode 100644 index 0000000000..a165e16fc3 --- /dev/null +++ b/src/main/java/nextstep/fp/SumStrategy.java @@ -0,0 +1,5 @@ +package nextstep.fp; + +public interface SumStrategy { + boolean option(int number); +} diff --git a/src/main/java/nextstep/ladder/LadderApplication.java b/src/main/java/nextstep/ladder/LadderApplication.java new file mode 100644 index 0000000000..c4c44b08a6 --- /dev/null +++ b/src/main/java/nextstep/ladder/LadderApplication.java @@ -0,0 +1,41 @@ +package nextstep.ladder; + +import nextstep.ladder.domain.Ladder; +import nextstep.ladder.domain.LadderResults; +import nextstep.ladder.domain.User; +import nextstep.ladder.domain.Users; +import nextstep.ladder.view.InputView; +import nextstep.ladder.view.OutputView; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +public class LadderApplication { + + public static void main(String[] args) { + + List names = InputView.inputUserNames(); + Users users = new Users(names); + + List results = InputView.inputLadderResult(); + LadderResults ladderResults = new LadderResults(results); + + int height = InputView.inputLadderHeight(); + + Ladder ladder = Ladder.createLadder(users.getUsers().size(), height, () -> new Random().nextBoolean()); + OutputView.display(users, ladder, ladderResults); + + List usersAfter = users.getUsers().stream() + .map(user -> user.rideLadder(ladder)) + .collect(Collectors.toList()); + + String name = InputView.inputUserName(); + + if (name.equals("all")) { + OutputView.announceAllUsers(usersAfter, ladderResults); + return; + } + OutputView.announceUser(name, usersAfter, ladderResults); + } +} diff --git a/src/main/java/nextstep/ladder/domain/BridgeStrategy.java b/src/main/java/nextstep/ladder/domain/BridgeStrategy.java new file mode 100644 index 0000000000..6eb94d125a --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/BridgeStrategy.java @@ -0,0 +1,6 @@ +package nextstep.ladder.domain; + +@FunctionalInterface +public interface BridgeStrategy { + Boolean bridgeBuild(); +} diff --git a/src/main/java/nextstep/ladder/domain/Ladder.java b/src/main/java/nextstep/ladder/domain/Ladder.java new file mode 100644 index 0000000000..c377a0aefa --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Ladder.java @@ -0,0 +1,44 @@ +package nextstep.ladder.domain; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class Ladder { + private List lines = new ArrayList<>(); + + public static Ladder createLadder(int countOfUsers, int height, BridgeStrategy strategy) { + return new Ladder(countOfUsers, height, strategy); + } + + private Ladder(int countOfUsers, int height, BridgeStrategy strategy) { + for (int i = 0; i < height; i++) { + Line line = Line.createLine(countOfUsers, strategy); + lines.add(line); + } + } + + public String status() { + String result = ""; + int height = lines.size(); + for (int i = 0; i < height; i++) { + Line line = lines.get(i); + result += line.status(); + } + return result; + } + + public int findLastPosition(int position) { + if (lines.isEmpty()) { + return position; + } + + int currentPosition = position; + for (Line line : lines) { + currentPosition = line.getNextPosition(currentPosition); + } + return currentPosition; + } +} diff --git a/src/main/java/nextstep/ladder/domain/LadderResult.java b/src/main/java/nextstep/ladder/domain/LadderResult.java new file mode 100644 index 0000000000..c6ba99be7f --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/LadderResult.java @@ -0,0 +1,10 @@ +package nextstep.ladder.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class LadderResult { + private String result; +} diff --git a/src/main/java/nextstep/ladder/domain/LadderResults.java b/src/main/java/nextstep/ladder/domain/LadderResults.java new file mode 100644 index 0000000000..483e30c3d4 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/LadderResults.java @@ -0,0 +1,25 @@ +package nextstep.ladder.domain; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class LadderResults { + private List ladderResultList = new ArrayList<>(); + + public LadderResults(List results) { + for (String result : results) { + ladderResultList.add(new LadderResult(result)); + } + } + + public String status() { + String result = ""; + for (LadderResult ladderResult : ladderResultList) { + result += ladderResult.getResult() + " "; + } + return result; + } +} diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java new file mode 100644 index 0000000000..73b5e71c10 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -0,0 +1,109 @@ +package nextstep.ladder.domain; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Getter +public class Line { + + private List bridges = new ArrayList<>(); + + public static Line createLine(int countOfPerson, BridgeStrategy strategy) { + Line line = new Line(countOfPerson, strategy); + validate(line); + return line; + } + + private static void validate(Line line) { + if (line.isInvalidBridge()) { + throw new RuntimeException("올바르지 않은 라인입니다."); + } + } + + private Line(int countOfPerson, BridgeStrategy strategy) { + for (int i = 0; i < countOfPerson - 1; i++) { + Optional prevIndex = Optional.ofNullable(i) + .map(o -> o - 1); + + Boolean expected = build(strategy); + bridges.add(decide(prevIndex, expected)); + } + } + + private static Boolean build(BridgeStrategy strategy) { + return strategy.bridgeBuild(); + } + + private Boolean decide(Optional prevIndex, Boolean expected) { + return prevIndex.filter(i -> i >= 0) + .map(i -> bridges.get(i)) + .map(b -> Boolean.TRUE.equals(b) ? Boolean.valueOf(false) : expected) + .orElse(expected); + } + + public int getNextPosition(int position) { + // bridges[position - 1] == T 이면 왼쪽으로 + Boolean toLeft = ableToLeft(position); + + // bridges[position] == T 이면 오른쪽으로 + Boolean toRight = ableToRight(position); + + if (toLeft && toRight) { + throw new RuntimeException("사다리 상태를 다시 확인해주세요."); + } + + if (toLeft) { + return position - 1; + } + + if (toRight) { + return position + 1; + } + + return position; + } + + public Boolean ableToRight(int position) { + return Optional.ofNullable(position) + .filter(o -> o < bridges.size()) + .map(o -> bridges.get(o)) + .filter(b -> b) + .orElse(false); + } + + public Boolean ableToLeft(int position) { + return Optional.ofNullable(position) + .map(o -> o - 1) + .filter(o -> o >= 0) + .map(o -> bridges.get(o)) + .filter(b -> b) + .orElse(false); + } + + public boolean isValidBridge() { + boolean valid = true; + for (int i = 0; i < bridges.size(); i++) { + if (ableToLeft(i) && ableToRight(i)) { + valid = false; + } + } + return valid; + } + public boolean isInvalidBridge() { + return !isValidBridge(); + } + + + public String status() { + String result = ""; + for (Boolean bridge : bridges) { + result += "|"; + result += bridge ? "-----" : " "; + } + result += "|\n"; + return result; + } +} diff --git a/src/main/java/nextstep/ladder/domain/User.java b/src/main/java/nextstep/ladder/domain/User.java new file mode 100644 index 0000000000..eb84817f27 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/User.java @@ -0,0 +1,31 @@ +package nextstep.ladder.domain; + +import lombok.Getter; + +@Getter +public class User { + private String name; + private int position; + + + public User(String name, int position) { + validateName(name); + + this.name = name; + this.position = position; + } + + private static void validateName(String name) { + if (name.length() > 5) { + throw new IllegalArgumentException("이름은 5글자까지 가능합니다."); + } + if (name.equals("all")) { + throw new IllegalArgumentException("all은 부적절한 이름입니다."); + } + } + + public User rideLadder(Ladder ladder) { + int lastPosition = ladder.findLastPosition(position); + return new User(name, lastPosition); + } +} diff --git a/src/main/java/nextstep/ladder/domain/Users.java b/src/main/java/nextstep/ladder/domain/Users.java new file mode 100644 index 0000000000..10fad2b8af --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Users.java @@ -0,0 +1,26 @@ +package nextstep.ladder.domain; + +import lombok.Getter; + +import java.util.*; +import java.util.stream.Collectors; + +@Getter +public class Users { + private List users = new ArrayList<>(); + + public Users(List names) { + for (int i = 0; i < names.size(); i++) { + User user = new User(names.get(i), i); + users.add(user); + } + } + + public String status() { + String result = ""; + for (User user : users) { + result += user.getName() + " "; + } + return result; + } +} diff --git a/src/main/java/nextstep/ladder/view/InputView.java b/src/main/java/nextstep/ladder/view/InputView.java new file mode 100644 index 0000000000..4a1ae0c2c7 --- /dev/null +++ b/src/main/java/nextstep/ladder/view/InputView.java @@ -0,0 +1,41 @@ +package nextstep.ladder.view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +import static java.lang.System.in; + +public class InputView { + private static final Scanner scanner = new Scanner(in); + public static final String ASKING_NAMES = "참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"; + public static final String ASKING_HEIGHT = "최대 사다리 높이는 몇 개인가요?"; + public static final String ASKING_LADDER_RESULT = "실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"; + public static final String ASKING_PLAYERS = "결과를 보고 싶은 사람은?"; + + public static List inputUserNames() { + System.out.println(ASKING_NAMES); + String next = scanner.next(); + return Arrays.stream(next.split(",")) + .collect(Collectors.toList()); + } + + public static int inputLadderHeight() { + System.out.println(ASKING_HEIGHT); + return scanner.nextInt(); + } + + public static List inputLadderResult() { + System.out.println(ASKING_LADDER_RESULT); + String next = scanner.next(); + return Arrays.stream(next.split(",")) + .collect(Collectors.toList()); + + } + + public static String inputUserName() { + System.out.println(ASKING_PLAYERS); + return scanner.next(); + } +} diff --git a/src/main/java/nextstep/ladder/view/OutputView.java b/src/main/java/nextstep/ladder/view/OutputView.java new file mode 100644 index 0000000000..31ab1bd712 --- /dev/null +++ b/src/main/java/nextstep/ladder/view/OutputView.java @@ -0,0 +1,28 @@ +package nextstep.ladder.view; + +import nextstep.ladder.domain.*; + +import java.util.List; + +public class OutputView { + + public static void display(Users users, Ladder ladder, LadderResults ladderResults) { + System.out.println("사다리 결과\n"); + System.out.println(users.status()); + System.out.println(ladder.status()); + System.out.println(ladderResults.status()); + } + + + public static void announceAllUsers(List usersAfter, LadderResults ladderResults) { + System.out.println("실행 결과"); + usersAfter.forEach(user -> System.out.println(user.getName() + " : " + ladderResults.getLadderResultList().get(user.getPosition()).getResult())); + } + + public static void announceUser(String name, List usersAfter, LadderResults ladderResults) { + System.out.println("실행 결과"); + usersAfter.stream() + .filter(user -> user.getName().equals(name)) + .forEach(user -> System.out.println(user.getName() + " : " + ladderResults.getLadderResultList().get(user.getPosition()).getResult())); + } +} diff --git a/src/main/java/nextstep/optional/Expression.java b/src/main/java/nextstep/optional/Expression.java index 1c98cd6a62..9937f2711e 100644 --- a/src/main/java/nextstep/optional/Expression.java +++ b/src/main/java/nextstep/optional/Expression.java @@ -1,5 +1,7 @@ package nextstep.optional; +import java.util.Arrays; + enum Expression { PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/"); @@ -14,12 +16,9 @@ private static boolean matchExpression(Expression e, String expression) { } static Expression of(String expression) { - for (Expression v : values()) { - if (matchExpression(v, expression)) { - return v; - } - } - - throw new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression)); + return Arrays.stream(values()) + .filter(v -> matchExpression(v, expression)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression))); } } diff --git a/src/main/java/nextstep/optional/User.java b/src/main/java/nextstep/optional/User.java index 9614c2f43f..bc2aee7eb9 100644 --- a/src/main/java/nextstep/optional/User.java +++ b/src/main/java/nextstep/optional/User.java @@ -1,5 +1,7 @@ package nextstep.optional; +import java.util.Optional; + public class User { private String name; private Integer age; @@ -33,7 +35,10 @@ public static boolean ageIsInRange1(User user) { } public static boolean ageIsInRange2(User user) { - return false; + return Optional.ofNullable(user) + .map(User::getAge) + .filter(age -> age >= 30 && age <= 45) + .isPresent(); } @Override diff --git a/src/main/java/nextstep/optional/Users.java b/src/main/java/nextstep/optional/Users.java index 6293040de8..63815d1c28 100644 --- a/src/main/java/nextstep/optional/Users.java +++ b/src/main/java/nextstep/optional/Users.java @@ -13,11 +13,9 @@ public class Users { new User("honux", 45)); User getUser(String name) { - for (User user : users) { - if (user.matchName(name)) { - return user; - } - } - return DEFAULT_USER; + return users.stream() + .filter(user -> user.matchName(name)) + .findFirst() + .orElse(DEFAULT_USER); } } diff --git a/src/test/java/nextstep/fp/CarTest.java b/src/test/java/nextstep/fp/CarTest.java index 1ab1106fe2..ecab481aec 100644 --- a/src/test/java/nextstep/fp/CarTest.java +++ b/src/test/java/nextstep/fp/CarTest.java @@ -8,24 +8,14 @@ public class CarTest { @Test public void 이동() { Car car = new Car("pobi", 0); - Car actual = car.move(new MoveStrategy() { - @Override - public boolean isMovable() { - return true; - } - }); + Car actual = car.move(() -> true); assertThat(actual).isEqualTo(new Car("pobi", 1)); } @Test public void 정지() { Car car = new Car("pobi", 0); - Car actual = car.move(new MoveStrategy() { - @Override - public boolean isMovable() { - return false; - } - }); + Car actual = car.move(() -> false); assertThat(actual).isEqualTo(new Car("pobi", 0)); } } diff --git a/src/test/java/nextstep/fp/LambdaTest.java b/src/test/java/nextstep/fp/LambdaTest.java index f240ac6560..0ad1940629 100644 --- a/src/test/java/nextstep/fp/LambdaTest.java +++ b/src/test/java/nextstep/fp/LambdaTest.java @@ -33,19 +33,19 @@ public void runThread() throws Exception { @Test public void sumAll() throws Exception { - int sum = Lambda.sumAll(numbers); + int sum = Lambda.sumAll(numbers, number -> true); assertThat(sum).isEqualTo(21); } @Test public void sumAllEven() throws Exception { - int sum = Lambda.sumAllEven(numbers); + int sum = Lambda.sumAll(numbers, number -> number % 2 == 0); assertThat(sum).isEqualTo(12); } @Test public void sumAllOverThree() throws Exception { - int sum = Lambda.sumAllOverThree(numbers); + int sum = Lambda.sumAll(numbers, number -> number > 3); assertThat(sum).isEqualTo(15); } } diff --git a/src/test/java/nextstep/ladder/domain/LadderTest.java b/src/test/java/nextstep/ladder/domain/LadderTest.java new file mode 100644 index 0000000000..0604078900 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LadderTest.java @@ -0,0 +1,58 @@ +package nextstep.ladder.domain; + +import jdk.jfr.Description; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class LadderTest { + + @ParameterizedTest + @CsvSource(value = { + "1000, 1000" + }) + @Description(value = "왼쪽으로도 오른쪽으로 건널 수 있는 다리는 생성되지 않음") + void 사다리_확인(int height, int people) { + Ladder ladder = Ladder.createLadder(people, height, () -> new Random().nextBoolean()); + ladder.getLines() + .forEach(line -> { + List bridges = line.getBridges(); + assertThat(bridges).hasSize(people - 1); + assertThat(line.isValidBridge()).isTrue(); + }); + } + + + public static Stream createSimpleLadder() { + return Stream.of( + /** + * users -> [a][b][c][d][e] + * lines -> |--| |--| | + * |--| |--| | + * |--| |--| | + * |--| |--| | + * |--| |--| | + * result ->[b][a][d][c][e] + */ + Arguments.of(Ladder.createLadder(5, 5, () -> true)) + ); + } + + @ParameterizedTest + @MethodSource(value = "createSimpleLadder") + void 다리_이동_테스트(Ladder ladder) { + assertThat(ladder.findLastPosition(0)).isEqualTo(1); + assertThat(ladder.findLastPosition(1)).isEqualTo(0); + assertThat(ladder.findLastPosition(2)).isEqualTo(3); + assertThat(ladder.findLastPosition(3)).isEqualTo(2); + assertThat(ladder.findLastPosition(4)).isEqualTo(4); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java new file mode 100644 index 0000000000..f071996e64 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -0,0 +1,48 @@ +package nextstep.ladder.domain; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.*; + +class LineTest { + + public static Stream preparingSeveralStrategy() { + return Stream.of( + Arguments.of((BridgeStrategy) () -> false, 5, 0), + Arguments.of((BridgeStrategy) () -> true, 5, 2), // 연속으로 다리를 놓을 수 없기 때문에 + Arguments.of((BridgeStrategy) () -> true, 1, 0) + ); + } + + @ParameterizedTest + @MethodSource(value = "preparingSeveralStrategy") + void 다리_세우기_전략에_대한_결과_테스트(BridgeStrategy strategy, int countOfPerson, int result) { + Line line = Line.createLine(countOfPerson, strategy); + assertThat(line.getBridges()).hasSize(countOfPerson - 1); + + long count = line.getBridges().stream() + .filter(b -> b) // 세워져 있는 다리 + .count(); + assertThat(count).isEqualTo(result); + } + + @Test + void 왼쪽으로_또는_오른쪽으로_이동한다() { + /** + * users : [a][b][c][d][e] + * liens : |--| |--| | + * results: [b][a][d][c][e] + */ + Line line = Line.createLine(5, () -> true); + assertThat(line.getNextPosition(0)).isEqualTo(1); + assertThat(line.getNextPosition(1)).isEqualTo(0); + assertThat(line.getNextPosition(2)).isEqualTo(3); + assertThat(line.getNextPosition(3)).isEqualTo(2); + assertThat(line.getNextPosition(4)).isEqualTo(4); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/UserTest.java b/src/test/java/nextstep/ladder/domain/UserTest.java new file mode 100644 index 0000000000..cefc3856ac --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/UserTest.java @@ -0,0 +1,43 @@ +package nextstep.ladder.domain; + +import org.assertj.core.api.Assertions; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + + +class UserTest { + + + public static Stream preparingUserAndLadder() { + return Stream.of( + Arguments.of(new User("test", 0), Ladder.createLadder(1, 5, () -> true), 0), + Arguments.of(new User("test", 0), Ladder.createLadder(5, 5, () -> true), 1), + Arguments.of(new User("test", 4), Ladder.createLadder(5, 5, () -> true), 4), + Arguments.of(new User("test", 3), Ladder.createLadder(1000, 200, () -> false), 3) + ); + } + + @ParameterizedTest + @MethodSource(value = "preparingUserAndLadder") + void rideLadder(User user, Ladder ladder, int lastPosition) { + User afterRiding = user.rideLadder(ladder); + Assertions.assertThat(afterRiding.getPosition()).isEqualTo(lastPosition); + Assertions.assertThat(afterRiding.getName()).isEqualTo(user.getName()); + } + + @ParameterizedTest + @CsvSource(value = { + "tooLong", + "abcdef", + "all" + }) + void nameTest(String name) { + Assertions.assertThatThrownBy(() -> new User(name, 0)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file