Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.6.0 #151

Merged
merged 1 commit into from
Dec 10, 2019
Merged

1.6.0 #151

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

Back to [Readme](README.md).

## [1.5.3] - UNRELEASED
## [1.6.0] - 2019-12-10

### Changed

* Cucable is now more resilient when trying to deal with unparsable features - these are skipped instead of stopping the overall execution.

### Fixed

* Utf-8 encoding error on linux (#150)
* Scenarios had too many tags when there were also feature tags (#145)

## [1.5.3] - 2019-09-09

### Added

Expand Down Expand Up @@ -271,6 +282,7 @@ Back to [Readme](README.md).

Initial project version on GitHub and Maven Central.

[1.6.0]: https://github.com/trivago/cucable-plugin/compare/1.5.3...1.6.0
[1.5.3]: https://github.com/trivago/cucable-plugin/compare/1.5.2...1.5.3
[1.5.2]: https://github.com/trivago/cucable-plugin/compare/1.5.1...1.5.2
[1.5.1]: https://github.com/trivago/cucable-plugin/compare/1.5.0...1.5.1
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
[![codecov](https://codecov.io/gh/trivago/cucable-plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/trivago/cucable-plugin)
[![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/bischoffdev)

---

### Note:

This project is feature-complete. Expect only bug fixes at this time.
For new projects, you should consider using Cucumber's native parallelization feature instead.

Thanks to everyone using, testing and improving Cucable over the last years!

---

![Cucumber compatible](documentation/img/cucumber-compatible-black-64.png)

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
Expand All @@ -16,6 +27,7 @@

- [Cucable Maven Plugin](#cucable-maven-plugin)
- [Cucumber 4](#cucumber-4)
- [Cucumber 5](#cucumber-5)
- [Repository Structure](#repository-structure)
- [Changelog](#changelog)
- [Maven dependency](#maven-dependency)
Expand Down Expand Up @@ -84,6 +96,10 @@ Even though Cucumber 4 supports basic parallel runs, Cucable has more options th
* You don't need any test framework changes because Cucable runs before the framework invocations
* You have full control over your runners because of template variables and custom placeholders

## Cucumber 5

* Cucumber 5 (using testng or junit 5) can natively run features and scenarios in parallel. Cucable __can__ be used but does not __have__ to be.

## Repository Structure

* [plugin-code](plugin-code) contains the full plugin source code.
Expand Down
2 changes: 1 addition & 1 deletion example-project/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.trivago.rta</groupId>
<artifactId>cucable-test-project</artifactId>
<version>1.5.2</version>
<version>1.6.0</version>
<packaging>jar</packaging>

<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ Feature: MyTest1InTestFeature2
@scenario1Tag1
@scenario1Tag2
Scenario: Scenario 1 in MyTest1InTestFeature2
Given I do something
Given I do something

@Login
Scenario: Login
Given this is a given step
Given I am on a page with text 'İ'
8 changes: 4 additions & 4 deletions plugin-code/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.trivago.rta</groupId>
<artifactId>cucable-plugin</artifactId>
<version>1.5.3</version>
<version>1.6.0</version>
<url>https://github.com/trivago/cucable-plugin</url>

<name>Cucable Maven Plugin</name>
Expand Down Expand Up @@ -80,9 +80,9 @@
<tag.expressions.version>2.0.2</tag.expressions.version>
<apache.commons.version>3.9</apache.commons.version>

<mockito.version>3.0.0</mockito.version>
<junit5.vintage.version>5.5.1</junit5.vintage.version>
<openpojo.version>0.8.12</openpojo.version>
<mockito.version>3.2.0</mockito.version>
<junit5.vintage.version>5.6.0-M1</junit5.vintage.version>
<openpojo.version>0.8.13</openpojo.version>
</properties>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ private String getRenderedFeatureFileContent(List<SingleScenario> singleScenario

for (SingleScenario singleScenario : singleScenarios) {
renderedContent.append(LINE_SEPARATOR);
addTags(renderedContent, singleScenario.getScenarioTags());
List<String> scenarioTags = singleScenario.getScenarioTags();
if (scenarioTags != null && firstScenario.getFeatureTags() != null) {
scenarioTags.removeAll(firstScenario.getFeatureTags());
}
addTags(renderedContent, scenarioTags);
addTags(renderedContent, singleScenario.getExampleTags());

addNameAndDescription(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ private int generateRunnerClassesWithDesiredNumberOfFeatures(
* @throws CucablePluginException see {@link CucablePluginException}.
*/
private void generateRunnerClass(final List<String> generatedFeatureFileNames) throws CucablePluginException {

// The runner class name will be equal to the feature name if there is only one feature to run.
// Otherwise, a generated runner class name is used.
String runnerClassName;
Expand Down
4 changes: 2 additions & 2 deletions plugin-code/src/main/java/com/trivago/files/FileIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class FileIO {
*/
public void writeContentToFile(String content, String filePath) throws FileCreationException {
try {
FileUtils.fileWrite(filePath, content);
FileUtils.fileWrite(filePath, "UTF-8", content);
} catch (IOException e) {
throw new FileCreationException(filePath);
}
Expand All @@ -53,7 +53,7 @@ public void writeContentToFile(String content, String filePath) throws FileCreat
*/
public String readContentFromFile(String filePath) throws MissingFileException {
try {
return FileUtils.fileRead(filePath);
return FileUtils.fileRead(filePath, "UTF-8");
} catch (IOException e) {
throw new MissingFileException(filePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,23 @@
package com.trivago.gherkin;

import com.trivago.exceptions.CucablePluginException;
import com.trivago.logging.CucableLogger;
import com.trivago.properties.PropertyManager;
import com.trivago.vo.DataTable;
import com.trivago.vo.SingleScenario;
import com.trivago.vo.Step;
import gherkin.AstBuilder;
import gherkin.Parser;
import gherkin.ParserException;
import gherkin.ast.Background;
import gherkin.ast.Examples;
import gherkin.ast.Feature;
import gherkin.ast.GherkinDocument;
import gherkin.ast.Scenario;
import gherkin.ast.ScenarioDefinition;
import gherkin.ast.ScenarioOutline;
import gherkin.ast.*;
import io.cucumber.tagexpressions.Expression;
import io.cucumber.tagexpressions.TagExpressionException;
import io.cucumber.tagexpressions.TagExpressionParser;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
Expand All @@ -52,16 +48,18 @@ public class GherkinDocumentParser {
private final GherkinToCucableConverter gherkinToCucableConverter;
private final GherkinTranslations gherkinTranslations;
private final PropertyManager propertyManager;
private final CucableLogger cucableLogger;

@Inject
GherkinDocumentParser(
final GherkinToCucableConverter gherkinToCucableConverter,
final GherkinTranslations gherkinTranslations,
final PropertyManager propertyManager
) {
final PropertyManager propertyManager,
final CucableLogger logger) {
this.gherkinToCucableConverter = gherkinToCucableConverter;
this.gherkinTranslations = gherkinTranslations;
this.propertyManager = propertyManager;
this.cucableLogger = logger;
}

/**
Expand All @@ -81,6 +79,10 @@ public List<SingleScenario> getSingleScenariosFromFeature(
GherkinDocument gherkinDocument = getGherkinDocumentFromFeatureFileContent(escapedFeatureContent);

Feature feature = gherkinDocument.getFeature();
if (feature == null) {
return Collections.emptyList();
}

String featureName = feature.getKeyword() + ": " + feature.getName();
String featureLanguage = feature.getLanguage();
String featureDescription = feature.getDescription();
Expand Down Expand Up @@ -161,7 +163,6 @@ public List<SingleScenario> getSingleScenariosFromFeature(
* @param featureLanguage The feature language this scenario outline belongs to.
* @param featureTags The feature tags of the parent feature.
* @param backgroundSteps Return a Cucable {@link SingleScenario} list.
* @throws CucablePluginException Thrown when the scenario outline does not contain an example table.
*/
private List<SingleScenario> getSingleScenariosFromOutline(
final ScenarioOutline scenarioOutline,
Expand All @@ -171,7 +172,7 @@ private List<SingleScenario> getSingleScenariosFromOutline(
final String featureDescription,
final List<String> featureTags,
final List<Step> backgroundSteps
) throws CucablePluginException {
) {

// Retrieve the translation of "Scenario" in the target language and add it to the scenario
String translatedScenarioKeyword = gherkinTranslations.getScenarioKeyword(featureLanguage);
Expand All @@ -185,7 +186,8 @@ private List<SingleScenario> getSingleScenariosFromOutline(
List<Step> steps = gherkinToCucableConverter.convertGherkinStepsToCucableSteps(scenarioOutline.getSteps());

if (scenarioOutline.getExamples().isEmpty()) {
throw new CucablePluginException("Scenario outline without examples table!");
cucableLogger.warn("Scenario outline without example table!");
return outlineScenarios;
}

for (Examples exampleTable : scenarioOutline.getExamples()) {
Expand Down Expand Up @@ -314,7 +316,7 @@ private GherkinDocument getGherkinDocumentFromFeatureFileContent(final String fe
}

if (gherkinDocument == null || gherkinDocument.getFeature() == null) {
throw new CucablePluginException("Could not parse features from gherkin document!");
cucableLogger.warn("No parsable gherkin.");
}

return gherkinDocument;
Expand All @@ -326,7 +328,7 @@ private GherkinDocument getGherkinDocumentFromFeatureFileContent(final String fe
*
* @param singleScenario a single scenario object.
* @return true if an include tag and no exclude tags are included in the source tag list and scenario name
* (if specified) matches.
* (if specified) matches.
*/
private boolean scenarioShouldBeIncluded(SingleScenario singleScenario) throws CucablePluginException {

Expand Down Expand Up @@ -354,10 +356,10 @@ private boolean scenarioShouldBeIncluded(SingleScenario singleScenario) throws C
/**
* Checks if a scenarioName value matches with the scenario name.
*
* @param language Feature file language ("en", "ro" etc).
* @param language Feature file language ("en", "ro" etc).
* @param stringToMatch the string that will be matched with the scenarioName value.
* @return index of the scenarioName value in the scenarioNames list if a match exists.
* -1 if no match exists.
* -1 if no match exists.
*/
public int matchScenarioWithScenarioNames(String language, String stringToMatch) {
List<String> scenarioNames = propertyManager.getScenarioNames();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.trivago.gherkin;

import com.trivago.exceptions.CucablePluginException;
import com.trivago.logging.CucableLogger;
import com.trivago.properties.PropertyManager;
import com.trivago.vo.DataTable;
import com.trivago.vo.SingleScenario;
Expand All @@ -15,25 +16,28 @@
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.times;

public class GherkinDocumentParserTest {

private GherkinDocumentParser gherkinDocumentParser;
private PropertyManager propertyManager;
private CucableLogger mockedLogger;

@Before
public void setup() {
GherkinToCucableConverter gherkinToCucableConverter = new GherkinToCucableConverter();
GherkinTranslations gherkinTranslations = new GherkinTranslations();
propertyManager = mock(PropertyManager.class);
gherkinDocumentParser = new GherkinDocumentParser(gherkinToCucableConverter, gherkinTranslations, propertyManager);
mockedLogger = mock(CucableLogger.class);
gherkinDocumentParser = new GherkinDocumentParser(gherkinToCucableConverter, gherkinTranslations, propertyManager, mockedLogger);
}

@Test(expected = CucablePluginException.class)
@Test
public void invalidFeatureTest() throws Exception {
gherkinDocumentParser.getSingleScenariosFromFeature("", "", null);
verify(mockedLogger, times(1)).warn("No parsable gherkin.");
}

@Test
Expand Down