Skip to content

Commit

Permalink
[bdd-engine] Add ability to load ExamplesTable-s from variables (#1947)
Browse files Browse the repository at this point in the history
  • Loading branch information
valfirst authored Sep 8, 2021
1 parent dbb5558 commit d498139
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 71 deletions.
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 @@ -24,25 +24,29 @@
import org.jbehave.core.io.LoadFromClasspath;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.vividus.bdd.examples.IExamplesTableLoader;
import org.vividus.bdd.steps.VariableResolver;

public class StoryLoader extends LoadFromClasspath
{
private final VariableResolver variableResolver;
private IExamplesTableLoader examplesTableLoader;
private ResourcePatternResolver resourcePatternResolver;

public StoryLoader()
public StoryLoader(VariableResolver variableResolver)
{
super(StandardCharsets.UTF_8);
this.variableResolver = variableResolver;
}

@Override
public String loadResourceAsText(String resourcePath)
{
if ("table".equals(FilenameUtils.getExtension(resourcePath)))
String path = (String) variableResolver.resolve(resourcePath);
if ("table".equals(FilenameUtils.getExtension(path)))
{
return examplesTableLoader.loadExamplesTable(resourcePath);
return examplesTableLoader.loadExamplesTable(path);
}
return super.loadResourceAsText(resourcePath);
return super.loadResourceAsText(path);
}

@Override
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 @@ -26,29 +26,17 @@
import org.springframework.core.io.Resource;
import org.vividus.bdd.resource.IBddResourceLoader;
import org.vividus.bdd.resource.ResourceLoadException;
import org.vividus.bdd.steps.VariableResolver;

public class ExamplesTableFileLoader implements IExamplesTableLoader
{
private static final Map<String, String> TABLES_CACHE = new ConcurrentHashMap<>();
private IBddResourceLoader bddResourceLoader;
private VariableResolver variableResolver;
private boolean cacheTables;

@Override
public String loadExamplesTable(String exampleTablePath)
public String loadExamplesTable(String tablePath)
{
String tablePath = (String) variableResolver.resolve(exampleTablePath);
String table;
if (cacheTables)
{
table = TABLES_CACHE.computeIfAbsent(tablePath, this::loadTable);
}
else
{
table = loadTable(tablePath);
}
return table;
return cacheTables ? TABLES_CACHE.computeIfAbsent(tablePath, this::loadTable) : loadTable(tablePath);
}

private String loadTable(String exampleTablePath)
Expand All @@ -69,11 +57,6 @@ public void setBddResourceLoader(IBddResourceLoader bddResourceLoader)
this.bddResourceLoader = bddResourceLoader;
}

public void setVariableResolver(VariableResolver variableResolver)
{
this.variableResolver = variableResolver;
}

public void setCacheTables(boolean cacheTables)
{
this.cacheTables = cacheTables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@

<bean id="examplesTableLoader" class="org.vividus.bdd.examples.ExamplesTableFileLoader">
<property name="bddResourceLoader" ref="bddResourceLoader" />
<property name="variableResolver" ref="variableResolver" />
<property name="cacheTables" value="${bdd.cache-examples-table}" />
</bean>

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 @@ -20,53 +20,59 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.io.ClassRelativeResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.vividus.bdd.examples.IExamplesTableLoader;
import org.vividus.bdd.resource.ResourceLoadException;
import org.vividus.bdd.steps.VariableResolver;

@ExtendWith(MockitoExtension.class)
class StoryLoaderTests
{
private static final String STORY_FILENAME = "unittest.story";
private static final String STORY_CONTENT = "unittest";

@Mock
private ResourcePatternResolver resourcePatternResolver;

@Mock
private IExamplesTableLoader examplesTableLoader;

@InjectMocks
private StoryLoader storyLoader;
@Mock private VariableResolver variableResolver;
@Mock private ResourcePatternResolver resourcePatternResolver;
@Mock private IExamplesTableLoader examplesTableLoader;
@InjectMocks private StoryLoader storyLoader;

private final ResourceLoader resourceLoader = new ClassRelativeResourceLoader(getClass());

@BeforeEach
void beforeEach()
{
storyLoader.setResourcePatternResolver(resourcePatternResolver);
storyLoader.setExamplesTableLoader(examplesTableLoader);
}

@Test
void testLoadResourceAsText()
{
Resource resource = resourceLoader.getResource(STORY_FILENAME);
when(resourcePatternResolver.getResource(STORY_FILENAME)).thenReturn(resource);
String actual = storyLoader.loadResourceAsText(STORY_FILENAME);
assertEquals(STORY_CONTENT, actual.trim());
var preProcessedStoryPath = "${unit}test.story";
var storyPath = "unittest.story";
when(variableResolver.resolve(preProcessedStoryPath)).thenReturn(storyPath);
Resource resource = resourceLoader.getResource(storyPath);
when(resourcePatternResolver.getResource(storyPath)).thenReturn(resource);
String actual = storyLoader.loadResourceAsText(preProcessedStoryPath);
assertEquals("unittest", actual.trim());
}

@Test
void shouldThrowResourceLoadException() throws IOException
{
String resourcePath = "resourcePath";
var resourcePath = "resourcePath";
when(variableResolver.resolve(resourcePath)).thenReturn(resourcePath);
Resource resource = mock(Resource.class);
when(resourcePatternResolver.getResource(resourcePath)).thenReturn(resource);
ResourceLoadException ioException = new ResourceLoadException("Resource IOException");
Expand All @@ -77,9 +83,9 @@ void shouldThrowResourceLoadException() throws IOException
@Test
void testLoadStoryAsText()
{
StoryLoader spy = Mockito.spy(storyLoader);
String storyPath = "storyPath";
String expected = "resource";
var storyPath = "storyPath";
var expected = "resource";
StoryLoader spy = spy(storyLoader);
doReturn(expected).when(spy).loadResourceAsText(storyPath);
String actual = spy.loadStoryAsText(storyPath);
assertEquals(expected, actual);
Expand All @@ -88,8 +94,9 @@ void testLoadStoryAsText()
@Test
void testLoadExamplesTableAsText()
{
String tablePath = "unittest.table";
String tableContent = "tableContent";
var tablePath = "unittest.table";
var tableContent = "tableContent";
when(variableResolver.resolve(tablePath)).thenReturn(tablePath);
when(examplesTableLoader.loadExamplesTable(tablePath)).thenReturn(tableContent);
String actual = storyLoader.loadResourceAsText(tablePath);
assertEquals(tableContent, actual);
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 @@ -34,60 +34,49 @@
import org.springframework.core.io.ResourceLoader;
import org.vividus.bdd.resource.BddResourceLoader;
import org.vividus.bdd.resource.ResourceLoadException;
import org.vividus.bdd.steps.VariableResolver;

@ExtendWith(MockitoExtension.class)
class ExamplesTableFileLoaderTests
{
private static final String PRE_PROCESSED = "${unit}test.table";
private static final String TABLE_FILENAME = "unittest.table";
private static final String TABLE_CONTENT = "|header1|";

@Mock
private BddResourceLoader bddResourceLoader;

@Mock
private VariableResolver variableResolver;

@InjectMocks
private ExamplesTableFileLoader examplesTableFileLoader;
@Mock private BddResourceLoader bddResourceLoader;
@InjectMocks private ExamplesTableFileLoader examplesTableFileLoader;

private final ResourceLoader resourceLoader = new ClassRelativeResourceLoader(getClass());

@Test
void testLoadExamplesTable()
{
Resource resource = resourceLoader.getResource(TABLE_FILENAME);
when(variableResolver.resolve(PRE_PROCESSED)).thenReturn(TABLE_FILENAME);
when(bddResourceLoader.getResource(TABLE_FILENAME)).thenReturn(resource);
String actual = examplesTableFileLoader.loadExamplesTable(PRE_PROCESSED);
String actual = examplesTableFileLoader.loadExamplesTable(TABLE_FILENAME);
assertEquals(TABLE_CONTENT, actual.trim());
}

@Test
void shouldCacheExamplesTableByPath()
{
Resource resource = resourceLoader.getResource(TABLE_FILENAME);
when(variableResolver.resolve(PRE_PROCESSED)).thenReturn(TABLE_FILENAME);
when(bddResourceLoader.getResource(TABLE_FILENAME)).thenReturn(resource);
examplesTableFileLoader.setCacheTables(true);
assertEquals(TABLE_CONTENT, examplesTableFileLoader.loadExamplesTable(PRE_PROCESSED).trim());
assertEquals(TABLE_CONTENT, examplesTableFileLoader.loadExamplesTable(PRE_PROCESSED).trim());
assertEquals(TABLE_CONTENT, examplesTableFileLoader.loadExamplesTable(TABLE_FILENAME).trim());
assertEquals(TABLE_CONTENT, examplesTableFileLoader.loadExamplesTable(TABLE_FILENAME).trim());
verify(bddResourceLoader).getResource(TABLE_FILENAME);
}

@Test
void testLoadExamplesTableWithIOException() throws IOException
{
String resourcePath = "resourcePath";
var resourcePath = "resourcePath";
Resource resource = mock(Resource.class);
when(variableResolver.resolve(PRE_PROCESSED)).thenReturn(resourcePath);
when(bddResourceLoader.getResource(resourcePath)).thenReturn(resource);
String exceptionMessage = "Resource IOException";
IOException ioException = new IOException(exceptionMessage);
when(resource.getInputStream()).thenThrow(ioException);
ResourceLoadException exception = assertThrows(ResourceLoadException.class,
() -> examplesTableFileLoader.loadExamplesTable(PRE_PROCESSED));
() -> examplesTableFileLoader.loadExamplesTable(resourcePath));
assertEquals(exceptionMessage, exception.getMessage());
assertEquals(ioException, exception.getCause());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@ bdd.configuration.skip-story-if-given-story-failed=true
bdd.configuration.composite-paths=steps/integration/*.steps
rest-api.http.cookie-store-level=scenario

bdd.variables.global.examples-table-path=/data/tables/locales/ca/locale-based.table

bdd.story-loader.batch-1.resource-location=story/integration
bdd.story-loader.batch-1.resource-include-patterns=*.story
bdd.story-loader.batch-1.resource-exclude-patterns=Precondition*.story
bdd.batch-1.meta-filters=groovy: !skip && epic != 'vividus-plugin-ssh' && !locale || locale.toString().tokenize(' ').contains('${bdd.variables.batch-1.locale}')
bdd.batch-1.threads=5
bdd.batch-1.story-execution-timeout=PT10M
bdd.variables.batch-1.locale=ca
bdd.batch-1.meta-filters=groovy: !skip && epic != 'vividus-plugin-ssh' && !locale || locale.toString().tokenize(' ').contains('${bdd.variables.batch-1.locale}')

bdd.story-loader.batch-2.resource-location=story/integration
bdd.story-loader.batch-2.resource-include-patterns=Batch-level variables and meta-filters.story
bdd.variables.batch-2.locale=th
bdd.batch-2.meta-filters=groovy: !skip && !locale || locale.toString().tokenize(' ').contains('${bdd.variables.batch-2.locale}')
bdd.batch-2.name=Locale: TH
bdd.variables.batch-2.locale=th
bdd.variables.batch-2.examples-table-path=/data/tables/locales/th/locale-based.table

bdd.story-loader.batch-3.resource-location=story/integration
bdd.story-loader.batch-3.resource-include-patterns=Batch-level variables and meta-filters.story
bdd.variables.batch-3.locale=us
bdd.batch-3.meta-filters=groovy: !skip && !locale || locale.toString().tokenize(' ').contains('${bdd.variables.batch-3.locale}')
bdd.batch-3.name=Locale: US
bdd.variables.batch-3.locale=us
bdd.variables.batch-3.examples-table-path=/data/tables/locales/us/locale-based.table

ui.visual.ignored-elements=By.id(some_fake_id)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Meta:
@epic vividus-bdd-engine
@feature variables

Lifecycle:
Examples:
${examples-table-path}

Scenario: Generic
Then `<commonVar>` is equal to `common`
Then `<localeBasedVar>` is not equal to `common`

Scenario: Thailand
Meta:
@locale th
Then `<localeBasedVar>` is equal to `th`

Scenario: North America
Meta:
@locale us ca
Then `<localeBasedVar>` is equal to `na`

0 comments on commit d498139

Please sign in to comment.