Skip to content

Commit

Permalink
Possible fix for serenity-bdd#712
Browse files Browse the repository at this point in the history
  • Loading branch information
wakaleo committed Mar 8, 2017
1 parent 83695a7 commit 09ec3d7
Showing 1 changed file with 36 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import net.serenitybdd.core.di.DependencyInjector;
import net.serenitybdd.core.exceptions.StepInitialisationException;
import net.serenitybdd.core.injectors.EnvironmentDependencyInjector;
Expand All @@ -21,10 +22,7 @@

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static com.google.common.collect.ImmutableSet.copyOf;
import static net.thucydides.core.steps.construction.ConstructionStrategy.*;
Expand Down Expand Up @@ -66,8 +64,9 @@ public StepFactory() {
* Returns a new ScenarioSteps instance, of the specified type.
* This is actually a proxy that allows reporting and screenshots to
* be performed at each step.
*
* @param scenarioStepsClass the scenario step class
* @param <T> the scenario step class type
* @param <T> the scenario step class type
* @return the instrumented step library
*/
public <T> T getStepLibraryFor(final Class<T> scenarioStepsClass) {
Expand Down Expand Up @@ -138,15 +137,15 @@ private <T> void injectOtherDependenciesInto(T steps) {
List<DependencyInjector> dependencyInjectors = dependencyInjectorService.findDependencyInjectors();
dependencyInjectors.addAll(getDefaultDependencyInjectors());

for(DependencyInjector dependencyInjector : dependencyInjectors) {
for (DependencyInjector dependencyInjector : dependencyInjectors) {
dependencyInjector.injectDependenciesInto(steps);
}
}

private ImmutableList<? extends DependencyInjector> getDefaultDependencyInjectors() {
return (pages != null) ?
ImmutableList.of(new PageObjectDependencyInjector(pages),
new EnvironmentDependencyInjector()) :
new EnvironmentDependencyInjector()) :
ImmutableList.of(new EnvironmentDependencyInjector());
}

Expand Down Expand Up @@ -176,8 +175,8 @@ private <T> T createProxyStepLibrary(Class<T> scenarioStepsClass,
} else if (STEP_LIBRARY_WITH_PAGES.equals(strategy)) {
return stepLibraryWithPages(scenarioStepsClass, e);
} else if (CONSTRUCTOR_WITH_PARAMETERS.equals(strategy) && parameters.length > 0) {
return immutableStepLibrary(scenarioStepsClass, e, parameters);
} else{
return immutableStepLibrary(scenarioStepsClass, e, parameters);
} else {
return (T) e.create();
}
}
Expand All @@ -187,7 +186,7 @@ private <T> T immutableStepLibrary(Class<T> scenarioStepsClass, Enhancer e, Obje
}

private Class<?>[] argumentTypesFrom(Class<?> scenarioStepsClass, Object[] parameters) {
for (Constructor<?> candidateConstructor :scenarioStepsClass.getDeclaredConstructors()) {
for (Constructor<?> candidateConstructor : inOrderOfIncreasingParameters(scenarioStepsClass.getDeclaredConstructors())) {
Class<?>[] parameterTypes = candidateConstructor.getParameterTypes();
if (parametersMatchFor(parameters, parameterTypes)) {
return parameterTypes;
Expand All @@ -196,18 +195,35 @@ private Class<?>[] argumentTypesFrom(Class<?> scenarioStepsClass, Object[] param
throw new IllegalArgumentException("Could not find a matching constructor for class " + scenarioStepsClass + "with parameters " + Arrays.toString(parameters));
}

private Constructor<?>[] inOrderOfIncreasingParameters(Constructor<?>[] declaredConstructors) {
List<Constructor<?>> sortedConstructors = Lists.newArrayList(declaredConstructors);
Collections.sort(sortedConstructors,
new Comparator<Constructor<?>>() {
@Override
public int compare(Constructor<?> o1, Constructor<?> o2) {
return Integer.compare(o1.getParameterTypes().length, o2.getParameterTypes().length);
}
});
return sortedConstructors.toArray(new Constructor<?>[]{});
}

private boolean parametersMatchFor(Object[] parameters, Class<?>[] parameterTypes) {
int parameterNumber = 0;
if (parameters.length != parameterTypes.length) {
return false;
} else {
for (Class<?> parameterType : parameterTypes) {

if (parameterNumber >= parameterTypes.length) {
return false;
}

if (parameter(parameters[parameterNumber]).cannotBeAssignedTo(parameterType)) {
return false;
}

if ((parameters[parameterNumber] != null)
&& (!ClassUtils.isAssignable(parameters[parameterNumber].getClass(),parameterType))) {
&& (!ClassUtils.isAssignable(parameters[parameterNumber].getClass(), parameterType))) {
return false;
}
parameterNumber++;
Expand All @@ -221,7 +237,9 @@ private ParameterAssignementChecker parameter(Object parameter) {
}

private Class<?> forTheClassOfParameter(Object parameter) {
if (parameter == null) { return Object.class; }
if (parameter == null) {
return Object.class;
}

return parameter.getClass();
}
Expand Down Expand Up @@ -251,11 +269,11 @@ public PageInjector(Pages pages) {
}

public <T> T injectPagesInto(final Class<T> stepLibraryClass, T newStepLibrary) {
if (ScenarioSteps.class.isAssignableFrom(stepLibraryClass)) {
if (ScenarioSteps.class.isAssignableFrom(stepLibraryClass)) {
((ScenarioSteps) newStepLibrary).setPages(pages);
} else if (StepLibraryType.ofClass(stepLibraryClass).hasAPagesField()) {
ImmutableSet<Field> fields = copyOf(Fields.of(stepLibraryClass).allFields());
Field pagesField = Iterables.find(fields, ofTypePages());
Field pagesField = Iterables.find(fields, ofTypePages());
pagesField.setAccessible(true);
try {
pagesField.set(newStepLibrary, pages);
Expand Down Expand Up @@ -291,9 +309,11 @@ public ParameterAssignementChecker(Object parameter) {
}

public boolean cannotBeAssignedTo(Class<?> parameterType) {
if (parameter == null) { return PARAMETER_CAN_BE_ASSIGNED; }
if (parameter == null) {
return PARAMETER_CAN_BE_ASSIGNED;
}

return (!ClassUtils.isAssignable(parameter.getClass(),parameterType));
return (!ClassUtils.isAssignable(parameter.getClass(), parameterType));
}
}
}

0 comments on commit 09ec3d7

Please sign in to comment.