diff --git a/src/test/java/eu/ztsh/training/hackerrank/EnvironmentTest.java b/src/test/java/eu/ztsh/training/hackerrank/EnvironmentTest.java index 5fe0e22..fda2bda 100644 --- a/src/test/java/eu/ztsh/training/hackerrank/EnvironmentTest.java +++ b/src/test/java/eu/ztsh/training/hackerrank/EnvironmentTest.java @@ -2,6 +2,7 @@ package eu.ztsh.training.hackerrank; import java.util.List; import java.util.Scanner; + import eu.ztsh.training.hackerrank.SolutionClassDescription.FieldModifier; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/eu/ztsh/training/hackerrank/HackerRankTest.java b/src/test/java/eu/ztsh/training/hackerrank/HackerRankTest.java index cf59987..106f212 100644 --- a/src/test/java/eu/ztsh/training/hackerrank/HackerRankTest.java +++ b/src/test/java/eu/ztsh/training/hackerrank/HackerRankTest.java @@ -7,13 +7,18 @@ import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +/** + * Common class with all the necessary logic + */ public abstract class HackerRankTest { @BeforeAll public static void setUpStreams() { + // Redirect stdout & stderr to own streams System.setOut(new PrintStream(outContent)); System.setErr(new PrintStream(errContent)); } @@ -27,14 +32,19 @@ public abstract class HackerRankTest { protected List invoke(List input) { try { + // reset our stdout as check is based on it outContent.reset(); + // write content to args of Solution#main writeLines(input); + // check if scanner has other name than "scanner" if (getSolutionClassDescription().fieldName() != null) { ReflectionHelper.reloadScanner(getSolutionClassDescription()); } + // run Solution#main getSolutionClassDescription().targetClass() .getMethod("main", String[].class) .invoke(null, (Object) new String[]{}); + // return intercepted output return readLines(); } catch (final NoSuchMethodException | InvocationTargetException | IllegalAccessException | NoSuchFieldException e) { diff --git a/src/test/java/eu/ztsh/training/hackerrank/ReflectionHelper.java b/src/test/java/eu/ztsh/training/hackerrank/ReflectionHelper.java index 498becf..d00b23e 100644 --- a/src/test/java/eu/ztsh/training/hackerrank/ReflectionHelper.java +++ b/src/test/java/eu/ztsh/training/hackerrank/ReflectionHelper.java @@ -5,9 +5,12 @@ import java.lang.invoke.VarHandle; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Scanner; + import eu.ztsh.training.hackerrank.SolutionClassDescription.FieldModifier; - +/** + * Util that helps with scanner declared outside Solution#main + */ public class ReflectionHelper { // https://stackoverflow.com/a/56043252 @@ -21,7 +24,15 @@ public class ReflectionHelper { } } - static void reloadScanner(SolutionClassDescription description) throws NoSuchFieldException, IllegalAccessException { + /** + * Modify scanner field to substitute it with custom readable one + * + * @param description Solution class parameters + * @throws NoSuchFieldException when there description.fieldName points to incorrect name + * @throws IllegalAccessException on scanner substitution error + */ + static void reloadScanner(SolutionClassDescription description) + throws NoSuchFieldException, IllegalAccessException { // https://stackoverflow.com/a/3301720 var scannerField = description.hasModifier(FieldModifier.STATIC) ? description.targetClass().getDeclaredField(description.fieldName()) diff --git a/src/test/java/eu/ztsh/training/hackerrank/SolutionClassDescription.java b/src/test/java/eu/ztsh/training/hackerrank/SolutionClassDescription.java index b141262..2ac51dd 100644 --- a/src/test/java/eu/ztsh/training/hackerrank/SolutionClassDescription.java +++ b/src/test/java/eu/ztsh/training/hackerrank/SolutionClassDescription.java @@ -2,6 +2,13 @@ package eu.ztsh.training.hackerrank; import java.util.Arrays; +/** + * Solution params definition + * + * @param targetClass Solution + * @param fieldName scanner field name + * @param modifiers scanner field modifiers + */ public record SolutionClassDescription(Class targetClass, String fieldName, FieldModifier[] modifiers) { SolutionClassDescription(Class targetClass) {