Skip to content

Commit

Permalink
[bdd-engine] Fix examples resolution for sub-steps (#1419)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikalinin1 authored Feb 12, 2021
1 parent 930fc48 commit 0b5d2db
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public void example(Map<String, String> tableRow, int exampleIndex)
runningScenario.setIndex(exampleIndex);
runningScenario.setTitle(runningScenario.getScenario().getTitle()
+ (exampleIndex == -1 ? "" : " [" + (exampleIndex + 1) + ']'));
runningScenario.setExample(tableRow);
super.example(tableRow, exampleIndex);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -53,7 +53,8 @@ public SubStepsConverter(ExtendedConfiguration configuration, IBddRunContext bdd
.collect(collectingAndThen(Collectors.toList(), DelegatingStoryReporter::new));
}
ExamplesTable subStepsTable = configuration.examplesTableFactory().createExamplesTable(subSteps);
List<Step> steps = stepExamplesTableParser.parse(subStepsTable);
List<Step> steps = stepExamplesTableParser.parse(subStepsTable,
bddRunContext.getRunningStory().getRunningScenario().getExample());
return new SubSteps(configuration, storyReporter, embedder, steps);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.vividus.bdd.model;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.jbehave.core.model.Scenario;
Expand All @@ -25,6 +27,7 @@ public class RunningScenario
private Scenario scenario;
private boolean failed;
private String title;
private Map<String, String> example = new HashMap<>();
private int index = -1;

public Scenario getScenario()
Expand Down Expand Up @@ -66,4 +69,14 @@ public void setIndex(int index)
{
this.index = index;
}

public Map<String, String> getExample()
{
return example;
}

public void setExample(Map<String, String> example)
{
this.example = example;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,11 +17,12 @@
package org.vividus.bdd.parser;

import java.util.List;
import java.util.Map;

import org.jbehave.core.model.ExamplesTable;
import org.jbehave.core.steps.Step;

public interface IStepExamplesTableParser
{
List<Step> parse(ExamplesTable stepsAsTable);
List<Step> parse(ExamplesTable stepsAsTable, Map<String, String> currentExample);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,7 @@
import org.jbehave.core.model.Scenario;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.Step;
import org.vividus.bdd.context.IBddRunContext;
import org.vividus.bdd.spring.ExtendedConfiguration;

public class StepExamplesTableParser implements IStepExamplesTableParser
Expand All @@ -36,14 +37,15 @@ public class StepExamplesTableParser implements IStepExamplesTableParser
private final ExtendedConfiguration configuration;
private final InjectableStepsFactory stepsFactory;

public StepExamplesTableParser(ExtendedConfiguration configuration, InjectableStepsFactory stepsFactory)
public StepExamplesTableParser(ExtendedConfiguration configuration, InjectableStepsFactory stepsFactory,
IBddRunContext bddRunContext)
{
this.configuration = configuration;
this.stepsFactory = stepsFactory;
}

@Override
public List<Step> parse(ExamplesTable stepsAsTable)
public List<Step> parse(ExamplesTable stepsAsTable, Map<String, String> currentExample)
{
Validate.isTrue(List.of(STEP_COLUMN_NAME).equals(stepsAsTable.getHeaders()),
"The steps examples table must have only one column with the name '%s', but got %s", STEP_COLUMN_NAME,
Expand All @@ -60,7 +62,7 @@ public List<Step> parse(ExamplesTable stepsAsTable)
Scenario scenario = new Scenario(stepsAsText);
MatchingStepMonitor monitor = new MatchingStepMonitor(configuration.stepMonitor());
return configuration.stepCollector().collectScenarioSteps(stepsFactory.createCandidateSteps(),
scenario, Map.of(), monitor);
scenario, currentExample, monitor);
}

private static String getErrorMessage(List<String> headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -131,7 +132,7 @@ void testFailed()
@Test
void testScenarioExamplesTable()
{
RunningScenario runningScenario = new RunningScenario();
RunningScenario runningScenario = spy(RunningScenario.class);
runningScenario.setScenario(scenario);
RunningStory runningStory = mockGetRunningStory();
runningStory.setRunningScenario(runningScenario);
Expand All @@ -141,6 +142,7 @@ void testScenarioExamplesTable()
assertEquals(1, runningScenario.getIndex());
assertEquals(String.format(TITLE_PATTERN, SCENARIO_TITLE, 2), runningScenario.getTitle());
verify(next).example(tableRow, 1);
verify(runningScenario).setExample(tableRow);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.jbehave.core.embedder.Embedder;
Expand All @@ -39,6 +40,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.vividus.bdd.context.IBddRunContext;
import org.vividus.bdd.model.RunningScenario;
import org.vividus.bdd.model.RunningStory;
import org.vividus.bdd.parser.IStepExamplesTableParser;
import org.vividus.bdd.spring.ExtendedConfiguration;
Expand All @@ -63,7 +65,13 @@ void testCreateSubSteps() throws IllegalAccessException
when(examplesTableFactory.createExamplesTable(stepsToExecute)).thenReturn(stepsToExecuteTable);
Step step = mock(Step.class);
List<Step> steps = List.of(step);
when(stepExamplesTableParser.parse(stepsToExecuteTable)).thenReturn(steps);
RunningStory runningStory = mock(RunningStory.class);
when(bddRunContext.getRunningStory()).thenReturn(runningStory);
RunningScenario runningScenario = mock(RunningScenario.class);
Map<String, String> examples = Map.of("key", "value");
when(runningScenario.getExample()).thenReturn(examples);
when(runningStory.getRunningScenario()).thenReturn(runningScenario);
when(stepExamplesTableParser.parse(stepsToExecuteTable, examples)).thenReturn(steps);
StoryReporter storyReporter = mockStoryReporter();
SubSteps executor = subStepsConverter.convertValue(stepsToExecute, SubSteps.class);
assertEquals(steps, getFieldValue("steps", executor));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import java.util.Map;

import org.jbehave.core.model.Scenario;
import org.junit.jupiter.api.Test;
Expand All @@ -42,4 +43,10 @@ void testGetNullRunningScenarioTitle()
runningScenario.setScenario(new Scenario(title, List.of()));
assertEquals(title, runningScenario.getTitle());
}

@Test
void shouldReturnEmptyExampleByDefault()
{
assertEquals(Map.of(), new RunningScenario().getExample());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,6 +50,7 @@
@ExtendWith(MockitoExtension.class)
class StepExamplesTableParserTests
{
private static final Map<String, String> PARAMETERS = Map.of("key", "value");
private static final String STEP = "When I do something";
private static final String ERROR_MESSAGE_PART = "The steps examples table must have only one column with the name"
+ " 'step', but got ";
Expand All @@ -67,7 +68,8 @@ class StepExamplesTableParserTests
void testMoreThanOneColumnInStepsExampleTable()
{
ExamplesTable table = new ExamplesTable("|step|col2|col3|\n|val1|val2|val3|");
Exception exception = assertThrows(IllegalArgumentException.class, () -> stepExamplesTableParser.parse(table));
Exception exception = assertThrows(IllegalArgumentException.class, () -> stepExamplesTableParser.parse(table,
Map.of()));
assertEquals(ERROR_MESSAGE_PART + "step, col2, col3", exception.getMessage());
verifyNoInteractions(stepsFactory, configuration);
}
Expand All @@ -76,7 +78,7 @@ void testMoreThanOneColumnInStepsExampleTable()
void testGetListStepsNoStepsAsTable()
{
Exception exception = assertThrows(IllegalArgumentException.class,
() -> stepExamplesTableParser.parse(ExamplesTable.EMPTY));
() -> stepExamplesTableParser.parse(ExamplesTable.EMPTY, Map.of()));
assertEquals(ERROR_MESSAGE_PART + "empty table", exception.getMessage());
verifyNoInteractions(stepsFactory, configuration);
}
Expand All @@ -97,7 +99,7 @@ void testGetListSteps()
return scenarioSteps.size() == 1 && STEP.equals(scenarioSteps.get(0));
});
ExamplesTable stepsToExecute = newStepExamplesTable(STEP);
stepExamplesTableParser.parse(stepsToExecute);
stepExamplesTableParser.parse(stepsToExecute, PARAMETERS);
verify(configuration).storyParser();
verify(configuration).stepMonitor();
}
Expand All @@ -106,7 +108,7 @@ private void mockStepCreation(ArgumentMatcher<Scenario> matcher)
{
Step step = mock(Step.class);
List<Step> steps = List.of(step);
when(mockStepCollector().collectScenarioSteps(eq(mockCandidateSteps()), argThat(matcher), eq(Map.of()),
when(mockStepCollector().collectScenarioSteps(eq(mockCandidateSteps()), argThat(matcher), eq(PARAMETERS),
any(MatchingStepMonitor.class))).thenReturn(steps);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@ Then `0` is = `1`

Composite: When I run composite step with table:$table
When I initialize scenario variable `table-from-composite-step` with values:<table>

Composite: When I use examples vars on the first level
Then `<var>` is = `<var2>`

Composite: When I use examples vars on the second level
When I use examples vars on the first level

Composite: When I use examples vars on the third level
When the condition `true` is true I do
|step |
|Then `<var3>` is = `<var4>` |
|When I use examples vars on the second level|
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Meta:
@epic vividus-core
@feature executable-steps
@issueId 805

Lifecycle:
Examples:
|var3|var4|
|1 |1 |

Scenario: Should resolve examples values in executable steps
When the condition `true` is true I do
|step |
|When I use examples vars on the first level |
|When I use examples vars on the second level|
|When I use examples vars on the third level |
When I use examples vars on the first level
When I use examples vars on the second level
When I use examples vars on the third level

Examples:
|var|var2|
|1 |1 |

0 comments on commit 0b5d2db

Please sign in to comment.