From f013132ea8085bc798f8b57a71a3711a4ac0f54d Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sat, 8 Jun 2024 19:36:05 +0530 Subject: [PATCH 1/8] Added assertAll and assertDoesNotThrow test --- .../functional/ExecutableTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java new file mode 100644 index 000000000..caf835304 --- /dev/null +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java @@ -0,0 +1,43 @@ +package io.reflectoring.functional; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class ExecutableTest { + + @ParameterizedTest + @CsvSource({"1,1,2,Hello,H,bye,2,byebye", "4,5,9,Good,Go,Go,-10,", "10,21,31,Team,Tea,Stop,-2,"}) + void testAssertAllExecutable( + int num1, + int num2, + int sum, + String input, + String prefix, + String arg, + int count, + String result) { + assertAll( + () -> assertEquals(sum, num1 + num2), + () -> assertTrue(input.startsWith(prefix)), + () -> { + if (count < 0) { + assertThrows( + IllegalArgumentException.class, + () -> { + new ArrayList<>(count); + }); + } else { + assertEquals(result, arg.repeat(count)); + } + }); + } + + @ParameterizedTest + @CsvSource({"one,0,o", "one,1,n"}) + void testAssertDoesNotThrow(String input, int index, char result) { + assertDoesNotThrow(() -> assertEquals(input.charAt(index), result)); + } +} From 580b0914c771bc82457312321a43eeadf10f5a93 Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sat, 8 Jun 2024 20:05:07 +0530 Subject: [PATCH 2/8] added test for assertThrows --- .../functional/ExecutableTest.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java index caf835304..264695fea 100644 --- a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java @@ -3,6 +3,9 @@ import static org.junit.jupiter.api.Assertions.*; import java.util.ArrayList; +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; @@ -10,7 +13,7 @@ public class ExecutableTest { @ParameterizedTest @CsvSource({"1,1,2,Hello,H,bye,2,byebye", "4,5,9,Good,Go,Go,-10,", "10,21,31,Team,Tea,Stop,-2,"}) - void testAssertAllExecutable( + void testAssertAllWithExecutable( int num1, int num2, int sum, @@ -37,7 +40,24 @@ void testAssertAllExecutable( @ParameterizedTest @CsvSource({"one,0,o", "one,1,n"}) - void testAssertDoesNotThrow(String input, int index, char result) { + void testAssertDoesNotThrowWithExecutable(String input, int index, char result) { assertDoesNotThrow(() -> assertEquals(input.charAt(index), result)); } + + @Test + void testAssertThrowsWithExecutable() { + List input = Arrays.asList("one", "", "three", null, "five"); + final IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> { + for (String value : input) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("Got invalid value"); + } + // process values + } + }); + assertEquals("Got invalid value", exception.getMessage()); + } } From 93a6a51d4247ff717081e79ef32b359dd60c0c68 Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sat, 8 Jun 2024 21:41:13 +0530 Subject: [PATCH 3/8] Added test for assertTimeout --- .../functional/ExecutableTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java index 264695fea..ec2256f36 100644 --- a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java @@ -2,12 +2,15 @@ import static org.junit.jupiter.api.Assertions.*; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.opentest4j.AssertionFailedError; public class ExecutableTest { @@ -60,4 +63,27 @@ void testAssertThrowsWithExecutable() { }); assertEquals("Got invalid value", exception.getMessage()); } + + @Test + void testAssertTimeoutWithExecutable() { + List numbers = Arrays.asList(100L, 200L, 50L, 300L, 5L, 0L, 12L, 80L); + final int delay = 2; + assertThrows( + AssertionFailedError.class, + () -> + assertTimeout( + Duration.ofSeconds(1), + () -> { + numbers.sort(Long::compareTo); + TimeUnit.SECONDS.sleep(delay); + })); + assertDoesNotThrow( + () -> + assertTimeout( + Duration.ofSeconds(5), + () -> { + numbers.sort(Long::compareTo); + TimeUnit.SECONDS.sleep(delay); + })); + } } From 253950057b64b4be385c5f6aad2e4dc751d351db Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sat, 8 Jun 2024 22:56:28 +0530 Subject: [PATCH 4/8] Added testAssertTimeoutWithExecutable --- .../functional/ExecutableTest.java | 73 +++++++++++++++---- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java index ec2256f36..5429d4854 100644 --- a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.opentest4j.AssertionFailedError; @@ -66,24 +67,64 @@ void testAssertThrowsWithExecutable() { @Test void testAssertTimeoutWithExecutable() { - List numbers = Arrays.asList(100L, 200L, 50L, 300L, 5L, 0L, 12L, 80L); + List numbers = Arrays.asList(100L, 200L, 50L, 300L); final int delay = 2; - assertThrows( - AssertionFailedError.class, + final Executable checkSorting = () -> assertEquals(List.of(50L, 100L, 200L, 300L), numbers); + assertAll( () -> - assertTimeout( - Duration.ofSeconds(1), - () -> { - numbers.sort(Long::compareTo); - TimeUnit.SECONDS.sleep(delay); - })); - assertDoesNotThrow( + assertThrows( + AssertionFailedError.class, + () -> + assertTimeout( + Duration.ofSeconds(1), + () -> { + TimeUnit.SECONDS.sleep(delay); + numbers.sort(Long::compareTo); + })), + checkSorting); + + assertAll( () -> - assertTimeout( - Duration.ofSeconds(5), - () -> { - numbers.sort(Long::compareTo); - TimeUnit.SECONDS.sleep(delay); - })); + assertDoesNotThrow( + () -> + assertTimeout( + Duration.ofSeconds(5), + () -> { + TimeUnit.SECONDS.sleep(delay); + numbers.sort(Long::compareTo); + })), + checkSorting); + } + + @Test + void testAssertTimeoutPreemptivelyWithExecutable() { + List numbers = Arrays.asList(100L, 200L, 50L, 300L); + final int delay = 2; + final Executable checkSorting = () -> assertEquals(List.of(50L, 100L, 200L, 300L), numbers); + final Executable noChanges = () -> assertEquals(List.of(100L, 200L, 50L, 300L), numbers); + assertAll( + () -> + assertThrows( + AssertionFailedError.class, + () -> + assertTimeoutPreemptively( + Duration.ofSeconds(1), + () -> { + TimeUnit.SECONDS.sleep(delay); + numbers.sort(Long::compareTo); + })), + noChanges); + + assertAll( + () -> + assertDoesNotThrow( + () -> + assertTimeoutPreemptively( + Duration.ofSeconds(5), + () -> { + TimeUnit.SECONDS.sleep(delay); + numbers.sort(Long::compareTo); + })), + checkSorting); } } From fd99e77b1d33bd8a83211b97b943cb6ff9183608 Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sun, 9 Jun 2024 17:31:50 +0530 Subject: [PATCH 5/8] Added test for ThrowingConsumer Added pom and ignore files. --- junit/junit5/functional-interfaces/.gitignore | 35 +++++++ junit/junit5/functional-interfaces/pom.xml | 41 ++++++++ .../functional/ValidationException.java | 7 ++ .../functional/ThrowingConsumerTest.java | 93 +++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 junit/junit5/functional-interfaces/.gitignore create mode 100644 junit/junit5/functional-interfaces/pom.xml create mode 100644 junit/junit5/functional-interfaces/src/main/java/io/reflectoring/functional/ValidationException.java create mode 100644 junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingConsumerTest.java diff --git a/junit/junit5/functional-interfaces/.gitignore b/junit/junit5/functional-interfaces/.gitignore new file mode 100644 index 000000000..57fb42c83 --- /dev/null +++ b/junit/junit5/functional-interfaces/.gitignore @@ -0,0 +1,35 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +.vscode + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/junit/junit5/functional-interfaces/pom.xml b/junit/junit5/functional-interfaces/pom.xml new file mode 100644 index 000000000..5b33f1e70 --- /dev/null +++ b/junit/junit5/functional-interfaces/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + io.reflectoring + junit5-functional-interfaces + 1.0-SNAPSHOT + + + 17 + 17 + 5.9.0 + + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + + diff --git a/junit/junit5/functional-interfaces/src/main/java/io/reflectoring/functional/ValidationException.java b/junit/junit5/functional-interfaces/src/main/java/io/reflectoring/functional/ValidationException.java new file mode 100644 index 000000000..a5d4f5d36 --- /dev/null +++ b/junit/junit5/functional-interfaces/src/main/java/io/reflectoring/functional/ValidationException.java @@ -0,0 +1,7 @@ +package io.reflectoring.functional; + +public class ValidationException extends Throwable { + public ValidationException(String message) { + super(message); + } +} diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingConsumerTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingConsumerTest.java new file mode 100644 index 000000000..b29cdc3f1 --- /dev/null +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingConsumerTest.java @@ -0,0 +1,93 @@ +package io.reflectoring.functional; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.text.MessageFormat; +import java.time.temporal.ValueRange; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.function.ThrowingConsumer; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class ThrowingConsumerTest { + @ParameterizedTest + @CsvSource({"50,true", "130,false", "-30,false"}) + void testMethodThatThrowsCheckedException(int percent, boolean valid) { + // acceptable percentage range: 0 - 100 + ValueRange validPercentageRange = ValueRange.of(0, 100); + final Function message = + input -> + MessageFormat.format( + "Percentage {0} should be in range {1}", input, validPercentageRange.toString()); + + ThrowingConsumer consumer = + input -> { + if (!validPercentageRange.isValidValue(input)) { + throw new ValidationException(message.apply(input)); + } + }; + + if (valid) { + assertDoesNotThrow(() -> consumer.accept(percent)); + } else { + assertAll( + () -> { + ValidationException exception = + assertThrows(ValidationException.class, () -> consumer.accept(percent)); + assertEquals(exception.getMessage(), message.apply(percent)); + }); + } + } + + @TestFactory + Stream testDynamicTestsWithThrowingConsumer() { + // acceptable percentage range: 0 - 100 + ValueRange validPercentageRange = ValueRange.of(0, 100); + final Function message = + input -> + MessageFormat.format( + "Percentage {0} should be in range {1}", input, validPercentageRange.toString()); + + // Define the ThrowingConsumer that validates the input percentage + ThrowingConsumer consumer = + testCase -> { + if (!validPercentageRange.isValidValue(testCase.percent)) { + throw new ValidationException(message.apply(testCase.percent)); + } + }; + + ThrowingConsumer executable = + testCase -> { + if (testCase.valid) { + assertDoesNotThrow(() -> consumer.accept(testCase)); + } else { + assertAll( + () -> { + ValidationException exception = + assertThrows(ValidationException.class, () -> consumer.accept(testCase)); + assertEquals(exception.getMessage(), message.apply(testCase.percent)); + }); + } + }; + // Test data: an array of test cases with inputs and their validity + Collection testCases = + Arrays.asList(new TestCase(50, true), new TestCase(130, false), new TestCase(-30, false)); + + Function displayNameGenerator = + testCase -> "Testing percentage: " + testCase.percent; + + // Generate dynamic tests + return DynamicTest.stream(testCases.stream(), displayNameGenerator, executable); + } + + // Helper record to represent a test case + record TestCase(int percent, boolean valid) {} +} From 3bf034c460e53ffd4bb6a0f71b07d97325910a5e Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sun, 9 Jun 2024 20:57:55 +0530 Subject: [PATCH 6/8] Added test on ThrowingSupplier --- .../functional/ThrowingSupplierTest.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingSupplierTest.java diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingSupplierTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingSupplierTest.java new file mode 100644 index 000000000..8df716242 --- /dev/null +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ThrowingSupplierTest.java @@ -0,0 +1,81 @@ +package io.reflectoring.functional; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeout; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.ThrowingSupplier; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.opentest4j.AssertionFailedError; + +public class ThrowingSupplierTest { + private final List numbers = Arrays.asList(100L, 200L, 50L, 300L); + private final Consumer> checkSorting = + list -> assertEquals(List.of(50L, 100L, 200L, 300L), list); + + ThrowingSupplier> sorter = + () -> { + if (numbers == null || numbers.isEmpty() || numbers.contains(null)) { + throw new ValidationException("Invalid input"); + } + TimeUnit.SECONDS.sleep(2); + return numbers.stream().sorted().toList(); + }; + + @ParameterizedTest + @CsvSource({"25.0d,5.0d", "36.0d,6.0d", "49.0d,7.0d"}) + void testDoesNotThrowWithSupplier(double input, double expected) { + ThrowingSupplier findSquareRoot = + () -> { + if (input < 0) { + throw new ValidationException("Invalid input"); + } + return Math.sqrt(input); + }; + assertEquals(expected, assertDoesNotThrow(findSquareRoot)); + } + + @Test + void testAssertTimeoutWithSupplier() { + // slow execution + assertThrows(AssertionFailedError.class, () -> assertTimeout(Duration.ofSeconds(1), sorter)); + + // fast execution + assertDoesNotThrow( + () -> { + List result = assertTimeout(Duration.ofSeconds(5), sorter); + checkSorting.accept(result); + }); + + // reset the number list and verify if the supplier validates it + Collections.fill(numbers, null); + + ValidationException exception = + assertThrows(ValidationException.class, () -> assertTimeout(Duration.ofSeconds(1), sorter)); + assertEquals("Invalid input", exception.getMessage()); + } + + @Test + void testAssertTimeoutPreemptivelyWithSupplier() { + // slow execution + assertThrows( + AssertionFailedError.class, () -> assertTimeoutPreemptively(Duration.ofSeconds(1), sorter)); + + // fast execution + assertDoesNotThrow( + () -> { + List result = assertTimeoutPreemptively(Duration.ofSeconds(5), sorter); + checkSorting.accept(result); + }); + } +} From e85b2bef44ef9def97b2c61f8bc93e5c72108507 Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Sun, 9 Jun 2024 23:08:01 +0530 Subject: [PATCH 7/8] updated code --- .../functional/ExecutableTest.java | 54 +++++-------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java index 5429d4854..dab8a5e17 100644 --- a/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java +++ b/junit/junit5/functional-interfaces/src/test/java/io/reflectoring/functional/ExecutableTest.java @@ -14,6 +14,15 @@ import org.opentest4j.AssertionFailedError; public class ExecutableTest { + private final List numbers = Arrays.asList(100L, 200L, 50L, 300L); + final Executable sorter = + () -> { + TimeUnit.SECONDS.sleep(2); + numbers.sort(Long::compareTo); + }; + private final Executable checkSorting = + () -> assertEquals(List.of(50L, 100L, 200L, 300L), numbers); + private final Executable noChanges = () -> assertEquals(List.of(100L, 200L, 50L, 300L), numbers); @ParameterizedTest @CsvSource({"1,1,2,Hello,H,bye,2,byebye", "4,5,9,Good,Go,Go,-10,", "10,21,31,Team,Tea,Stop,-2,"}) @@ -67,64 +76,27 @@ void testAssertThrowsWithExecutable() { @Test void testAssertTimeoutWithExecutable() { - List numbers = Arrays.asList(100L, 200L, 50L, 300L); - final int delay = 2; - final Executable checkSorting = () -> assertEquals(List.of(50L, 100L, 200L, 300L), numbers); assertAll( () -> assertThrows( - AssertionFailedError.class, - () -> - assertTimeout( - Duration.ofSeconds(1), - () -> { - TimeUnit.SECONDS.sleep(delay); - numbers.sort(Long::compareTo); - })), + AssertionFailedError.class, () -> assertTimeout(Duration.ofSeconds(1), sorter)), checkSorting); assertAll( - () -> - assertDoesNotThrow( - () -> - assertTimeout( - Duration.ofSeconds(5), - () -> { - TimeUnit.SECONDS.sleep(delay); - numbers.sort(Long::compareTo); - })), - checkSorting); + () -> assertDoesNotThrow(() -> assertTimeout(Duration.ofSeconds(5), sorter)), checkSorting); } @Test void testAssertTimeoutPreemptivelyWithExecutable() { - List numbers = Arrays.asList(100L, 200L, 50L, 300L); - final int delay = 2; - final Executable checkSorting = () -> assertEquals(List.of(50L, 100L, 200L, 300L), numbers); - final Executable noChanges = () -> assertEquals(List.of(100L, 200L, 50L, 300L), numbers); assertAll( () -> assertThrows( AssertionFailedError.class, - () -> - assertTimeoutPreemptively( - Duration.ofSeconds(1), - () -> { - TimeUnit.SECONDS.sleep(delay); - numbers.sort(Long::compareTo); - })), + () -> assertTimeoutPreemptively(Duration.ofSeconds(1), sorter)), noChanges); assertAll( - () -> - assertDoesNotThrow( - () -> - assertTimeoutPreemptively( - Duration.ofSeconds(5), - () -> { - TimeUnit.SECONDS.sleep(delay); - numbers.sort(Long::compareTo); - })), + () -> assertDoesNotThrow(() -> assertTimeoutPreemptively(Duration.ofSeconds(5), sorter)), checkSorting); } } From 12f71f67d7b0a1637be6d174a96cabaeb7f4a50e Mon Sep 17 00:00:00 2001 From: sagaofsilence Date: Mon, 10 Jun 2024 23:30:51 +0530 Subject: [PATCH 8/8] Added junit to build --- build-all.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-all.sh b/build-all.sh index 18c669d50..3c7e03954 100755 --- a/build-all.sh +++ b/build-all.sh @@ -211,6 +211,8 @@ then build_gradle_module "spring-data/spring-data-jdbc-converter" build_gradle_module "reactive" build_gradle_module "junit/assumptions" + build_maven_module "junit/junit5/junit5" + build_maven_module "junit/junit5/functional-interfaces" build_gradle_module "logging" build_gradle_module "pact/pact-feign-consumer"