diff options
Diffstat (limited to 'src/main/java/junitparams/custom')
6 files changed, 210 insertions, 0 deletions
diff --git a/src/main/java/junitparams/custom/CustomParameters.java b/src/main/java/junitparams/custom/CustomParameters.java new file mode 100644 index 0000000..06fd4a4 --- /dev/null +++ b/src/main/java/junitparams/custom/CustomParameters.java @@ -0,0 +1,25 @@ +package junitparams.custom; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Tells JUnitParams which {@link ParametersProvider} to use for parameters generation.<br> + * Use instead of {@link junitparams.Parameters} annotation. + * <p> + * Can also be used to create custom annotations.<br> + * Check {@link junitparams.FileParameters}, {@link FileParametersProvider} and CustomParametersProviderTest for usage examples. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +public @interface CustomParameters { + + /** + * @return Your custom parameters provider class. + */ + Class<? extends ParametersProvider> provider(); + +} diff --git a/src/main/java/junitparams/custom/FileParametersProvider.java b/src/main/java/junitparams/custom/FileParametersProvider.java new file mode 100644 index 0000000..746fe5c --- /dev/null +++ b/src/main/java/junitparams/custom/FileParametersProvider.java @@ -0,0 +1,62 @@ +package junitparams.custom; + +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; + +import junitparams.FileParameters; +import junitparams.mappers.DataMapper; + +public class FileParametersProvider implements ParametersProvider<FileParameters> { + + private FileParameters fileParameters; + + @Override + public void initialize(FileParameters fileParameters) { + this.fileParameters = fileParameters; + } + + @Override + public Object[] getParameters() { + return paramsFromFile(); + } + + private Object[] paramsFromFile() { + try { + Reader reader = createProperReader(); + DataMapper mapper = fileParameters.mapper().newInstance(); + try { + return mapper.map(reader); + } finally { + reader.close(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException( + "Could not successfully read parameters from file: " + fileParameters.value(), e); + } + } + + private Reader createProperReader() throws IOException { + String filepath = fileParameters.value(); + String encoding = fileParameters.encoding(); + + if (filepath.indexOf(':') < 0) { + return new FileReader(filepath); + } + + String protocol = filepath.substring(0, filepath.indexOf(':')); + String filename = filepath.substring(filepath.indexOf(':') + 1); + + if ("classpath".equals(protocol)) { + return new InputStreamReader(getClass().getClassLoader().getResourceAsStream(filename), encoding); + } else if ("file".equals(protocol)) { + return new InputStreamReader(new FileInputStream(filename), encoding); + } + + throw new IllegalArgumentException("Unknown file access protocol. Only 'file' and 'classpath' are supported!"); + } + +} diff --git a/src/main/java/junitparams/custom/ParametersProvider.java b/src/main/java/junitparams/custom/ParametersProvider.java new file mode 100644 index 0000000..8cf3621 --- /dev/null +++ b/src/main/java/junitparams/custom/ParametersProvider.java @@ -0,0 +1,26 @@ +package junitparams.custom; + +import java.lang.annotation.Annotation; + +/** + * An interface for custom parameters providers. To be used with {@link CustomParameters} annotation. + * Must have a default no-args constructor. + * + * @param <A> type of annotation mentioning this provider + */ +public interface ParametersProvider<A extends Annotation> { + + /** + * Initializes this provider - you can read your custom annotation config here. + * + * @param parametersAnnotation parameters annotation on test method + */ + void initialize(A parametersAnnotation); + + /** + * Actual parameters generation + * + * @return parameters for test method calls + */ + Object[] getParameters(); +} diff --git a/src/main/java/junitparams/custom/combined/Cartesian.java b/src/main/java/junitparams/custom/combined/Cartesian.java new file mode 100644 index 0000000..f98948f --- /dev/null +++ b/src/main/java/junitparams/custom/combined/Cartesian.java @@ -0,0 +1,46 @@ +package junitparams.custom.combined; + +import java.util.Arrays; +import java.util.List; + +class Cartesian { + + static Object[] getCartesianProductOf(List<Object[]> array) { + if (array == null || array.size() == 0) { + return new Object[]{}; + } + + for (int i = 0; i < array.size() - 1; i++) { + Object[] arrayOne = array.get(i); + Object[] arrayTwo = array.get(i + 1); + array.set(i + 1, cartesianProduct(arrayOne, arrayTwo)); + } + + return array.get(array.size() - 1); + } + + private static Object[] cartesianProduct(Object[] arrayOne, Object[] arrayTwo) { + int numberOfCombinations = arrayOne.length * arrayTwo.length; + Object[] resultArray = new Object[numberOfCombinations][2]; + + int i = 0; + for (Object firstElement : arrayOne) { + for (Object secondElement : arrayTwo) { + resultArray[i] = getCartesianOfTwoElements(firstElement, secondElement); + i++; + } + } + + return resultArray; + } + + private static Object getCartesianOfTwoElements(Object objectOne, Object objectTwo) { + if (!objectOne.getClass().isArray()) { + return new Object[]{objectOne, objectTwo}; + } + Object[] initialArray = (Object[]) objectOne; + Object[] newArray = Arrays.copyOf(initialArray, initialArray.length + 1); + newArray[newArray.length - 1] = objectTwo; + return newArray; + } +} diff --git a/src/main/java/junitparams/custom/combined/CombinedParameters.java b/src/main/java/junitparams/custom/combined/CombinedParameters.java new file mode 100644 index 0000000..95e4a5e --- /dev/null +++ b/src/main/java/junitparams/custom/combined/CombinedParameters.java @@ -0,0 +1,24 @@ +package junitparams.custom.combined; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import junitparams.custom.CustomParameters; + +@Retention(RetentionPolicy.RUNTIME) +@CustomParameters(provider = CombinedParametersProvider.class) +public @interface CombinedParameters { + /** + * Parameter values defined as a String array. + * Each of the elements is a list of values that should be tested for parameters. + * Using this annotation will result in creating a n-fold cartesian product of parameter values effectively testing + * each possible combination. + * Values in the array must match the test method's parameters in order and type. + * <p> + * Example:<br> + * <code>@CombinedParameters({"han,chewie","33,204"})<br> + * public void shouldTestAllNameAgeCombinations(String name, Integer age) + * </code> + */ + String[] value() default {}; +} diff --git a/src/main/java/junitparams/custom/combined/CombinedParametersProvider.java b/src/main/java/junitparams/custom/combined/CombinedParametersProvider.java new file mode 100644 index 0000000..382b6ce --- /dev/null +++ b/src/main/java/junitparams/custom/combined/CombinedParametersProvider.java @@ -0,0 +1,27 @@ +package junitparams.custom.combined; + +import java.util.ArrayList; +import java.util.List; + +import junitparams.custom.ParametersProvider; +import junitparams.internal.Utils; + +public class CombinedParametersProvider implements ParametersProvider<CombinedParameters> { + + private CombinedParameters combinedParameters; + + @Override + public void initialize(CombinedParameters parametersAnnotation) { + this.combinedParameters = parametersAnnotation; + } + + @Override + public Object[] getParameters() { + List<Object[]> list = new ArrayList<Object[]>(); + for(String parameterArray : combinedParameters.value()) { + list.add(Utils.splitAtCommaOrPipe(parameterArray)); + } + + return Cartesian.getCartesianProductOf(list); + } +} |