package cucumber.runtime.model;
import cucumber.runtime.io.Resource;
import cucumber.runtime.io.ResourceLoader;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class CucumberFeatureTest {
@Test
public void succeds_if_no_features_are_found() {
ResourceLoader resourceLoader = mock(ResourceLoader.class);
when(resourceLoader.resources("does/not/exist", ".feature")).thenReturn(Collections.<Resource>emptyList());
CucumberFeature.load(resourceLoader, singletonList("does/not/exist"), emptyList(), new PrintStream(new ByteArrayOutputStream()));
}
@Test
public void logs_message_if_no_features_are_found() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ResourceLoader resourceLoader = mock(ResourceLoader.class);
when(resourceLoader.resources("does/not/exist", ".feature")).thenReturn(Collections.<Resource>emptyList());
CucumberFeature.load(resourceLoader, singletonList("does/not/exist"), emptyList(), new PrintStream(baos));
assertEquals(String.format("No features found at [does/not/exist]%n"), baos.toString());
}
@Test
public void logs_message_if_features_are_found_but_filters_are_too_strict() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ResourceLoader resourceLoader = mockFeatureFileResource("features", "Feature: foo");
CucumberFeature.load(resourceLoader, singletonList("features"), singletonList((Object) "@nowhere"), new PrintStream(baos));
assertEquals(String.format("None of the features at [features] matched the filters: [@nowhere]%n"), baos.toString());
}
@Test
public void logs_message_if_no_feature_paths_are_given() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ResourceLoader resourceLoader = mock(ResourceLoader.class);
CucumberFeature.load(resourceLoader, Collections.<String>emptyList(), emptyList(), new PrintStream(baos));
assertEquals(String.format("Got no path to feature directory or feature file%n"), baos.toString());
}
@Test
public void applies_line_filters_when_loading_a_feature() throws Exception {
String featurePath = "path/foo.feature";
String feature = "" +
"Feature: foo\n" +
" Scenario: scenario 1\n" +
" * step\n" +
" Scenario: scenario 2\n" +
" * step\n";
ResourceLoader resourceLoader = mockFeatureFileResource(featurePath, feature);
List<CucumberFeature> features = CucumberFeature.load(
resourceLoader,
singletonList(featurePath + ":2"),
new ArrayList<Object>(),
new PrintStream(new ByteArrayOutputStream()));
assertEquals(1, features.size());
assertEquals(1, features.get(0).getFeatureElements().size());
assertEquals("Scenario: scenario 1", features.get(0).getFeatureElements().get(0).getVisualName());
}
@Test
public void loads_features_specified_in_rerun_file() throws Exception {
String featurePath1 = "path/bar.feature";
String feature1 = "" +
"Feature: bar\n" +
" Scenario: scenario bar\n" +
" * step\n";
String featurePath2 = "path/foo.feature";
String feature2 = "" +
"Feature: foo\n" +
" Scenario: scenario 1\n" +
" * step\n" +
" Scenario: scenario 2\n" +
" * step\n";
String rerunPath = "path/rerun.txt";
String rerunFile = featurePath1 + ":2 " + featurePath2 + ":4";
ResourceLoader resourceLoader = mockFeatureFileResource(featurePath1, feature1);
mockFeatureFileResource(resourceLoader, featurePath2, feature2);
mockFileResource(resourceLoader, rerunPath, null, rerunFile);
List<CucumberFeature> features = CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
new ArrayList<Object>(),
new PrintStream(new ByteArrayOutputStream()));
assertEquals(2, features.size());
assertEquals(1, features.get(0).getFeatureElements().size());
assertEquals("Scenario: scenario bar", features.get(0).getFeatureElements().get(0).getVisualName());
assertEquals(1, features.get(1).getFeatureElements().size());
assertEquals("Scenario: scenario 2", features.get(1).getFeatureElements().get(0).getVisualName());
}
@Test
public void loads_no_features_when_rerun_file_is_empty() throws Exception {
String feature = "" +
"Feature: bar\n" +
" Scenario: scenario bar\n" +
" * step\n";
String rerunPath = "path/rerun.txt";
String rerunFile = "";
ResourceLoader resourceLoader = mockFeatureFileResourceForAnyFeaturePath(feature);
mockFileResource(resourceLoader, rerunPath, null, rerunFile);
List<CucumberFeature> features = CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
new ArrayList<Object>(),
new PrintStream(new ByteArrayOutputStream()));
assertEquals(0, features.size());
}
@Test
public void loads_features_specified_in_rerun_file_from_classpath_when_not_in_file_system() throws Exception {
String featurePath = "path/bar.feature";
String feature = "" +
"Feature: bar\n" +
" Scenario: scenario bar\n" +
" * step\n";
String rerunPath = "path/rerun.txt";
String rerunFile = featurePath + ":2";
ResourceLoader resourceLoader = mockFeatureFileResource("classpath:" + featurePath, feature);
mockFeaturePathToNotExist(resourceLoader, featurePath);
mockFileResource(resourceLoader, rerunPath, suffix(null), rerunFile);
List<CucumberFeature> features = CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
new ArrayList<Object>(),
new PrintStream(new ByteArrayOutputStream()));
assertEquals(1, features.size());
assertEquals(1, features.get(0).getFeatureElements().size());
assertEquals("Scenario: scenario bar", features.get(0).getFeatureElements().get(0).getVisualName());
}
@Test
public void gives_error_message_if_path_from_rerun_file_does_not_exist() throws Exception {
String featurePath = "path/bar.feature";
String rerunPath = "path/rerun.txt";
String rerunFile = featurePath + ":2";
ResourceLoader resourceLoader = mock(ResourceLoader.class);
mockFeaturePathToNotExist(resourceLoader, featurePath);
mockFeaturePathToNotExist(resourceLoader, "classpath:" + featurePath);
mockFileResource(resourceLoader, rerunPath, suffix(null), rerunFile);
try {
CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
new ArrayList<Object>(),
new PrintStream(new ByteArrayOutputStream()));
fail("IllegalArgumentException was expected");
} catch (IllegalArgumentException exception) {
assertEquals("Neither found on file system or on classpath: " +
"Not a file or directory: path/bar.feature, No resource found for: classpath:path/bar.feature",
exception.getMessage());
}
}
@Test
public void gives_error_message_if_filters_conflicts_with_path_from_rerun_file_on_file_system() throws Exception {
String featurePath = "path/bar.feature";
String rerunPath = "path/rerun.txt";
String rerunFile = featurePath + ":2";
ResourceLoader resourceLoader = mockFeatureFileResource(featurePath, "");
mockFileResource(resourceLoader, rerunPath, suffix(null), rerunFile);
try {
CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
Collections.<Object>singletonList("@Tag"),
new PrintStream(new ByteArrayOutputStream()));
fail("IllegalArgumentException was expected");
} catch (IllegalArgumentException exception) {
assertEquals("Inconsistent filters: [@Tag, 2]. Only one type [line,name,tag] can be used at once.",
exception.getMessage());
}
}
@Test
public void gives_error_message_if_filters_conflicts_with_path_from_rerun_file_on_classpath() throws Exception {
String featurePath = "path/bar.feature";
String rerunPath = "path/rerun.txt";
String rerunFile = featurePath + ":2";
ResourceLoader resourceLoader = mockFeatureFileResource("classpath:" + featurePath, "");
mockFeaturePathToNotExist(resourceLoader, featurePath);
mockFileResource(resourceLoader, rerunPath, suffix(null), rerunFile);
try {
CucumberFeature.load(
resourceLoader,
singletonList("@" + rerunPath),
Collections.<Object>singletonList("@Tag"),
new PrintStream(new ByteArrayOutputStream()));
fail("IllegalArgumentException was expected");
} catch (IllegalArgumentException exception) {
assertEquals("Inconsistent filters: [@Tag, 2]. Only one type [line,name,tag] can be used at once.",
exception.getMessage());
}
}
private ResourceLoader mockFeatureFileResource(String featurePath, String feature)
throws IOException {
ResourceLoader resourceLoader = mock(ResourceLoader.class);
mockFeatureFileResource(resourceLoader, featurePath, feature);
return resourceLoader;
}
private ResourceLoader mockFeatureFileResourceForAnyFeaturePath(String feature)
throws IOException {
ResourceLoader resourceLoader = mock(ResourceLoader.class);
Resource resource = mock(Resource.class);
when(resource.getPath()).thenReturn("");
when(resource.getInputStream()).thenReturn(new ByteArrayInputStream(feature.getBytes("UTF-8")));
when(resourceLoader.resources(anyString(), anyString())).thenReturn(singletonList(resource));
return resourceLoader;
}
private void mockFeatureFileResource(ResourceLoader resourceLoader, String featurePath, String feature)
throws IOException {
mockFileResource(resourceLoader, featurePath, ".feature", feature);
}
private void mockFileResource(ResourceLoader resourceLoader, String featurePath, String extension, String feature)
throws IOException {
Resource resource = mock(Resource.class);
when(resource.getPath()).thenReturn(featurePath);
when(resource.getInputStream()).thenReturn(new ByteArrayInputStream(feature.getBytes("UTF-8")));
when(resourceLoader.resources(featurePath, extension)).thenReturn(singletonList(resource));
}
private void mockFeaturePathToNotExist(ResourceLoader resourceLoader, String featurePath) {
if (featurePath.startsWith("classpath")) {
when(resourceLoader.resources(featurePath, ".feature")).thenReturn(new ArrayList<Resource>());
} else {
when(resourceLoader.resources(featurePath, ".feature")).thenThrow(new IllegalArgumentException("Not a file or directory: " + featurePath));
}
}
private String suffix(String suffix) {
return suffix;
}
}