Skip to content

Commit

Permalink
Make data driver able to supply additional arguments again (#1818)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vampire authored Nov 8, 2023
1 parent 4893b85 commit c8c899f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void runParameterizedFeature(SpockExecutionContext context, ParameterizedFeature
try (IDataIterator dataIterator = new DataIteratorFactory(supervisor).createFeatureDataIterator(context)) {
IIterationRunner iterationRunner = createIterationRunner(context, childExecutor);
IDataDriver dataDriver = feature.getDataDriver();
dataDriver.runIterations(dataIterator, iterationRunner, feature.getFeatureMethod().getParameters().subList(0, feature.getDataVariables().size()));
dataDriver.runIterations(dataIterator, iterationRunner, feature.getFeatureMethod().getParameters());
childExecutor.awaitFinished();
} catch (InterruptedException ie) {
throw ie;
Expand All @@ -58,9 +58,9 @@ private IIterationRunner createIterationRunner(SpockExecutionContext context, Pa
private final AtomicInteger iterationIndex = new AtomicInteger(0);

@Override
public CompletableFuture<ExecutionResult> runIteration(Object[] dataValues, int estimatedNumIterations) {
public CompletableFuture<ExecutionResult> runIteration(Object[] args, int estimatedNumIterations) {
int currIterationIndex = iterationIndex.getAndIncrement();
IterationInfo iterationInfo = createIterationInfo(context, currIterationIndex, dataValues, estimatedNumIterations);
IterationInfo iterationInfo = createIterationInfo(context, currIterationIndex, args, estimatedNumIterations);
IterationNode iterationNode = new IterationNode(
context.getParentId().append("iteration", String.valueOf(currIterationIndex)),
context.getRunContext().getConfiguration(RunnerConfiguration.class), iterationInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Arrays;

import static java.lang.System.arraycopy;
import static java.util.Arrays.copyOfRange;
import static org.spockframework.runtime.model.MethodInfo.MISSING_ARGUMENT;

/**
Expand Down Expand Up @@ -220,8 +221,9 @@ void runIteration(SpockExecutionContext context, IterationInfo iterationInfo, Ru
getSpecificationContext(context).setCurrentIteration(null); // TODO check if we really need to null here
}

IterationInfo createIterationInfo(SpockExecutionContext context, int iterationIndex, Object[] dataValues, int estimatedNumIterations) {
IterationInfo createIterationInfo(SpockExecutionContext context, int iterationIndex, Object[] args, int estimatedNumIterations) {
FeatureInfo currentFeature = context.getCurrentFeature();
Object[] dataValues = copyOfRange(args, 0, currentFeature.getDataVariables().size());
IterationInfo result = new IterationInfo(currentFeature, iterationIndex, dataValues, estimatedNumIterations);
result.setName(currentFeature.getName());
String iterationName = currentFeature.getIterationNameProvider().getName(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ public interface IDataDriver {
*
* @param dataIterator the data iterator giving access to the data from the data providers. The data iterator is not to be closed by this method.
* @param iterationRunner the iteration runner that will be used to run the test method for each iteration.
* @param parameters the parameters of the test method representing data variables
* @param parameters the parameters of the test method
*/
void runIterations(IDataIterator dataIterator, IIterationRunner iterationRunner, List<ParameterInfo> parameters);

/**
* Prepares the arguments for the data variables for invocation of the test method.
* Prepares the arguments for invocation of the test method.
* <p>
* It is possible to have fewer arguments produced by the data driver than the number of data variables.
* It is possible to have fewer arguments produced by the data driver than the number of parameters.
* In this case, the missing arguments are filled with {@link MethodInfo#MISSING_ARGUMENT}.
* <p>
* Custom implementations of IDataDriver should use this method to prepare the argument array.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ public RepeatUntilFailureDataDriver(int maxAttempts) {
public void runIterations(IDataIterator dataIterator, IIterationRunner iterationRunner, List<ParameterInfo> parameters) {
int estimatedNumIterations = dataIterator.getEstimatedNumIterations();
int maxIterations = estimatedNumIterations * maxAttempts;
List<Object[]> data = new ArrayList<>(estimatedNumIterations);
dataIterator.forEachRemaining(data::add);
List<Object[]> arguments = new ArrayList<>(estimatedNumIterations);
dataIterator.forEachRemaining(arguments::add);
for (int attempt = 0; attempt < maxAttempts; attempt++) {
for (Object[] dataValues : data) {
for (Object[] args : arguments) {
try {
ExecutionResult executionResult = iterationRunner.runIteration(dataValues, maxIterations).get();
ExecutionResult executionResult = iterationRunner.runIteration(args, maxIterations).get();
if (executionResult == ExecutionResult.FAILED) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import spock.lang.Unroll
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy

import static org.junit.platform.testkit.engine.EventConditions.displayName
import static org.spockframework.runtime.model.MethodInfo.MISSING_ARGUMENT

/**
Expand Down Expand Up @@ -278,6 +279,53 @@ def foo() {
y = 2
}

def 'data variables and iteration index are rendered properly with additional arguments'() {
given:
runner.addClassImport(Foo)

when:
def result = runner.runSpecBody '''
@Foo
def 'a feature'(a) {
expect:
true
where:
x << [1, 2]
y << [3, 4]
}
'''

then:
result.testEvents().succeeded().assertEventsMatchExactly(
displayName('a feature [x: 1, y: 3, #0]'),
displayName('a feature [x: 2, y: 4, #1]'),
displayName('a feature')
)
}

def 'conditional annotations that check data values work properly with additional arguments'() {
given:
runner.addClassImport(Foo)

when:
runner.runSpecBody '''
@Foo
@Requires({ data.x })
def 'a feature'(a) {
expect:
true
where:
x = 1
y = 2
}
'''

then:
noExceptionThrown()
}

static class FooExtension implements IAnnotationDrivenExtension<Foo> {
@Override
void visitFixtureAnnotation(Foo annotation, MethodInfo fixtureMethod) {
Expand Down

0 comments on commit c8c899f

Please sign in to comment.