Skip to content

Commit

Permalink
Merge pull request #29 from theangrydev/master
Browse files Browse the repository at this point in the history
Allow custom parameter resolution for table tests
  • Loading branch information
danielbodart committed Mar 19, 2016
2 parents 1aa6b50 + 9464ee5 commit c6dbd26
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 39 deletions.
45 changes: 6 additions & 39 deletions src/com/googlecode/yatspec/junit/DecoratingFrameworkMethod.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package com.googlecode.yatspec.junit;

import com.googlecode.totallylazy.Sequence;
import com.googlecode.yatspec.rendering.ScenarioNameRendererFactory;
import com.googlecode.yatspec.state.ScenarioName;
import org.junit.runners.model.FrameworkMethod;

import java.lang.reflect.Array;
import java.util.Arrays;

import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.yatspec.junit.ParameterResolverFactory.parameterResolver;
import static java.util.Arrays.asList;

public class DecoratingFrameworkMethod extends FrameworkMethod {

private final Row row;

public DecoratingFrameworkMethod(FrameworkMethod method, Row row) {
Expand All @@ -20,39 +17,9 @@ public DecoratingFrameworkMethod(FrameworkMethod method, Row row) {
}

@Override
public Object invokeExplosively(Object target, Object... params) throws Throwable {
final Object[] suppliedParams = row.value();
final Class<?>[] requiredParams = getMethod().getParameterTypes();

if (requiresNoVarArgs(requiredParams)) {
return super.invokeExplosively(target, suppliedParams);
}

if (isMissingRequiredArguments(suppliedParams, requiredParams)) {
throw new IllegalArgumentException("Missing parameters.");
}

final Sequence<Object> preparedParams = sequence(suppliedParams).take(Math.min(requiredParams.length - 1, suppliedParams.length)).append(getVarargsFrom(suppliedParams, requiredParams));
return super.invokeExplosively(target, preparedParams.toArray());
}

private boolean requiresNoVarArgs(Class<?>[] methodParams) {
return !methodParams[methodParams.length - 1].isArray();
}

private boolean isMissingRequiredArguments(Object[] input, Class<?>[] expected) {
return input.length < expected.length - 1;
}

private boolean hasVarArgsSupplied(Object[] input, Class<?>[] expected) {
return input.length >= expected.length;
}

private Object getVarargsFrom(Object[] suppliedParams, Class<?>[] requiredParams) {
if (hasVarArgsSupplied(suppliedParams, requiredParams)) {
return Arrays.copyOfRange(suppliedParams, requiredParams.length - 1, suppliedParams.length);
}
return Array.newInstance(requiredParams[requiredParams.length - 1].getComponentType(), 0);
public Object invokeExplosively(Object test, Object... ignored) throws Throwable {
Object[] testMethodParameters = parameterResolver().resolveParameters(row, test.getClass(), getMethod());
return super.invokeExplosively(test, testMethodParameters);
}

@Override
Expand Down Expand Up @@ -80,4 +47,4 @@ public int hashCode() {
result = 31 * result + row.hashCode();
return result;
}
}
}
7 changes: 7 additions & 0 deletions src/com/googlecode/yatspec/junit/ParameterResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.googlecode.yatspec.junit;

import java.lang.reflect.Method;

public interface ParameterResolver {
Object[] resolveParameters(Row row, Class<?> testClass, Method testMethod) throws Exception;
}
22 changes: 22 additions & 0 deletions src/com/googlecode/yatspec/junit/ParameterResolverFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.googlecode.yatspec.junit;

import static com.googlecode.yatspec.Creator.create;
import static java.lang.Class.forName;
import static java.lang.System.getProperty;

public class ParameterResolverFactory {

public static final String PARAMETER_RESOLVER = "yatspec.parameter.resolver";

public static void setParameterResolver(Class<? extends ParameterResolver> aClass) {
System.setProperty(PARAMETER_RESOLVER, aClass.getName());
}

public static ParameterResolver parameterResolver() {
try {
return create(forName(getProperty(PARAMETER_RESOLVER, VarargsParameterResolver.class.getName())));
} catch (Exception e) {
return new VarargsParameterResolver();
}
}
}
45 changes: 45 additions & 0 deletions src/com/googlecode/yatspec/junit/VarargsParameterResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.googlecode.yatspec.junit;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;

import static com.googlecode.totallylazy.Sequences.sequence;

public class VarargsParameterResolver implements ParameterResolver {

@Override
public Object[] resolveParameters(Row row, Class<?> testClass, Method testMethod) throws Exception {
final Object[] suppliedParams = row.value();
final Class<?>[] requiredParams = testMethod.getParameterTypes();

if (requiresNoVarArgs(requiredParams)) {
return suppliedParams;
}

if (isMissingRequiredArguments(suppliedParams, requiredParams)) {
throw new IllegalArgumentException("Missing parameters.");
}

return sequence(suppliedParams).take(Math.min(requiredParams.length - 1, suppliedParams.length)).append(getVarargsFrom(suppliedParams, requiredParams)).toArray();
}

private boolean requiresNoVarArgs(Class<?>[] methodParams) {
return !methodParams[methodParams.length - 1].isArray();
}

private boolean isMissingRequiredArguments(Object[] input, Class<?>[] expected) {
return input.length < expected.length - 1;
}

private boolean hasVarArgsSupplied(Object[] input, Class<?>[] expected) {
return input.length >= expected.length;
}

private Object getVarargsFrom(Object[] suppliedParams, Class<?>[] requiredParams) {
if (hasVarArgsSupplied(suppliedParams, requiredParams)) {
return Arrays.copyOfRange(suppliedParams, requiredParams.length - 1, suppliedParams.length);
}
return Array.newInstance(requiredParams[requiredParams.length - 1].getComponentType(), 0);
}
}

0 comments on commit c6dbd26

Please sign in to comment.