package cucumber.runtime.autocomplete;
import cucumber.runtime.FeatureBuilder;
import cucumber.runtime.JdkPatternArgumentMatcher;
import cucumber.runtime.ParameterInfo;
import cucumber.runtime.StepDefinition;
import cucumber.runtime.io.Resource;
import cucumber.runtime.model.CucumberFeature;
import gherkin.I18n;
import gherkin.deps.com.google.gson.Gson;
import gherkin.deps.com.google.gson.GsonBuilder;
import gherkin.formatter.Argument;
import gherkin.formatter.model.Step;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
public class StepdefGeneratorTest {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
@Test
public void generates_code_completion_metadata() throws IOException {
StepdefGenerator meta = new StepdefGenerator();
List<StepDefinition> stepDefs = asList(def("I have (\\d+) cukes in my belly"), def("I have (\\d+) apples in my bowl"));
List<MetaStepdef> metadata = meta.generate(stepDefs, features());
String expectedJson = "" +
"[\n" +
" {\n" +
" \"source\": \"I have (\\\\d+) apples in my bowl\",\n" +
" \"flags\": \"\",\n" +
" \"steps\": []\n" +
" },\n" +
" {\n" +
" \"source\": \"I have (\\\\d+) cukes in my belly\",\n" +
" \"flags\": \"\",\n" +
" \"steps\": [\n" +
" {\n" +
" \"name\": \"I have 4 cukes in my belly\",\n" +
" \"args\": [\n" +
" {\n" +
" \"offset\": 7,\n" +
" \"val\": \"4\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"name\": \"I have 42 cukes in my belly\",\n" +
" \"args\": [\n" +
" {\n" +
" \"offset\": 7,\n" +
" \"val\": \"42\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
"]";
assertEquals(GSON.fromJson(expectedJson, new TypeReference<List<MetaStepdef>>() {
}.getType()), metadata);
}
private List<CucumberFeature> features() throws IOException {
List<CucumberFeature> features = new ArrayList<CucumberFeature>();
FeatureBuilder fb = new FeatureBuilder(features);
fb.parse(new Resource() {
@Override
public String getPath() {
return "test.feature";
}
@Override
public String getAbsolutePath() {
throw new UnsupportedOperationException();
}
@Override
public InputStream getInputStream() {
try {
return new ByteArrayInputStream(("" +
"Feature: Test\n" +
" Scenario: Test\n" +
" Given I have 4 cukes in my belly\n" +
" And I have 3 bananas in my basket\n" +
" Given I have 42 cukes in my belly\n")
.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public String getClassName(String extension) {
throw new UnsupportedOperationException();
}
}, emptyList());
return features;
}
private StepDefinition def(final String pattern) {
return new StepDefinition() {
Pattern regexp = Pattern.compile(pattern);
@Override
public List<Argument> matchedArguments(Step step) {
return new JdkPatternArgumentMatcher(regexp).argumentsFrom(step.getName());
}
@Override
public String getLocation(boolean detail) {
throw new UnsupportedOperationException();
}
@Override
public Integer getParameterCount() {
return null;
}
@Override
public ParameterInfo getParameterType(int n, Type argumentType) {
return null;
}
@Override
public void execute(I18n i18n, Object[] args) throws Throwable {
throw new UnsupportedOperationException();
}
@Override
public boolean isDefinedAt(StackTraceElement stackTraceElement) {
throw new UnsupportedOperationException();
}
@Override
public String getPattern() {
return pattern;
}
@Override
public boolean isScenarioScoped() {
return false;
}
};
}
public abstract static class TypeReference<T> {
private final Type type;
protected TypeReference() {
Type superclass = getClass().getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
}
public Type getType() {
return this.type;
}
}
}