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

[Java8] Replace ConstantPoolTypeIntrospector #1178

Merged
merged 3 commits into from
Jul 29, 2017
Merged
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
5 changes: 4 additions & 1 deletion History.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## [2.0.0-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v1.2.5...master) (In Git)

* [Java, Java8, Kotlin Java8] Support method references ([#1178](https://github.com/cucumber/cucumber-jvm/pull/1178), [#1140](https://github.com/cucumber/cucumber-jvm/pull/1140) M.P. Korstanje)
* Java8 method references can be used in lambda step definitions
* It is no longer possible to use lambda step definitions without also using `cucumber-java8`
* Lambda step definitions can be used in Kotlin. Function references are not yet understood
* [Core] Make the parsing of the rerun file more robust ([#1187](https://github.com/cucumber/cucumber-jvm/pull/1187) M.P. Korstanje)
* [Android] Update the version of the cucumber-jvm-deps dependency - to a version without Java8 bytecode ([#1170](https://github.com/cucumber/cucumber-jvm/pull/1170), [#893](https://github.com/cucumber/cucumber-jvm/issues/893) Björn Rasmusson)
* [Needle] Handle circular dependencies ([#853](https://github.com/cucumber/cucumber-jvm/pull/853) Lars Bilger)
Expand All @@ -25,7 +29,6 @@
* [Guice] Use the ContextClassLoader when loading InjectorSource. ([#1036](https://github.com/cucumber/cucumber-jvm/pull/1036), [#1037](https://github.com/cucumber/cucumber-jvm/pull/1037) Kyle Moore)
* [Core] Allow global registration of custom XStream converters. ([#1010](https://github.com/cucumber/cucumber-jvm/pull/1010), [#1009](https://github.com/cucumber/cucumber-jvm/issues/1009) Chris Rankin)
* [Spring] Support multithreaded execution of scenarios ([#1106](https://github.com/cucumber/cucumber-jvm/issues/1106), [#1107](https://github.com/cucumber/cucumber-jvm/issues/1107), [#1148](https://github.com/cucumber/cucumber-jvm/issues/1148), [#1153](https://github.com/cucumber/cucumber-jvm/pull/1153) Ismail Bhana, M.P. Korstanje)
* [Java8, Kotlin Java8] Support java 8 method references ([#1140](https://github.com/cucumber/cucumber-jvm/pull/1140) M.P. Korstanje)
* [Core] Show explicit error message when field name missed in table header ([#1014](https://github.com/cucumber/cucumber-jvm/pull/1014) Mykola Gurov)
* [Examples] Properly quit selenium in webbit examples ([#1146](https://github.com/cucumber/cucumber-jvm/pull/1146) Alberto Scotto)
* [JUnit] Use AssumptionFailed to mark scenarios/steps as skipped ([#1142](https://github.com/cucumber/cucumber-jvm/pull/1142) Björn Rasmusson)
Expand Down
11 changes: 0 additions & 11 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<parent>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm</artifactId>
<relativePath>../pom.xml</relativePath>
<version>2.0.0-SNAPSHOT</version>
</parent>

Expand All @@ -17,16 +16,6 @@
<groupId>io.cucumber</groupId>
<artifactId>cucumber-core</artifactId>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>gherkin</artifactId>
<scope>provided</scope>
Copy link
Contributor Author

@mpkorstanje mpkorstanje Jul 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are transitive dependencies through cucumber-core.

</dependency>

<dependency>
<groupId>io.cucumber</groupId>
Expand Down
60 changes: 20 additions & 40 deletions java/src/main/java/cucumber/runtime/java/JavaBackend.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package cucumber.runtime.java;

import static cucumber.runtime.io.MultiLoader.packageName;
import static cucumber.runtime.java.ObjectFactoryLoader.loadObjectFactory;
import static java.lang.Thread.currentThread;

import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.ObjectFactory;
import cucumber.api.java8.GlueBase;
import cucumber.api.java8.HookBody;
import cucumber.api.java8.HookNoArgsBody;
import cucumber.api.java8.StepdefBody;
import cucumber.runtime.Backend;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.CucumberException;
import cucumber.runtime.DuplicateStepDefinitionException;
import cucumber.runtime.Env;
import cucumber.runtime.Glue;
import cucumber.runtime.HookDefinition;
import cucumber.runtime.StepDefinition;
import cucumber.runtime.UnreportedStepExecutor;
import cucumber.runtime.Utils;
import cucumber.runtime.io.MultiLoader;
Expand All @@ -30,14 +33,12 @@
import java.util.List;
import java.util.regex.Pattern;

import static cucumber.runtime.io.MultiLoader.packageName;

public class JavaBackend implements Backend {
public static final ThreadLocal<JavaBackend> INSTANCE = new ThreadLocal<JavaBackend>();
private final SnippetGenerator snippetGenerator = new SnippetGenerator(createSnippet());

private Snippet createSnippet() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ClassLoader classLoader = currentThread().getContextClassLoader();
try {
classLoader.loadClass("cucumber.runtime.java8.LambdaGlueBase");
return new Java8Snippet();
Expand All @@ -59,24 +60,17 @@ private Snippet createSnippet() {
* @param resourceLoader
*/
public JavaBackend(ResourceLoader resourceLoader) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
methodScanner = new MethodScanner(classFinder);
objectFactory = ObjectFactoryLoader.loadObjectFactory(classFinder, Env.INSTANCE.get(ObjectFactory.class.getName()));
this(new ResourceLoaderClassFinder(resourceLoader, currentThread().getContextClassLoader()));
}

public JavaBackend(ObjectFactory objectFactory) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
methodScanner = new MethodScanner(classFinder);
this.objectFactory = objectFactory;
private JavaBackend(ClassFinder classFinder) {
this(loadObjectFactory(classFinder, Env.INSTANCE.get(ObjectFactory.class.getName())), classFinder);
}

public JavaBackend(ObjectFactory objectFactory, ClassFinder classFinder) {
this.objectFactory = objectFactory;
this.classFinder = classFinder;
methodScanner = new MethodScanner(classFinder);
this.objectFactory = objectFactory;
this.methodScanner = new MethodScanner(classFinder);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrote the constructors to be idiomatic java.

}

@Override
Expand Down Expand Up @@ -157,44 +151,30 @@ void addStepDefinition(Annotation annotation, Method method) {
}
}

public void addStepDefinition(String regexp, long timeoutMillis, StepdefBody body, TypeIntrospector typeIntrospector) {
try {
glue.addStepDefinition(new Java8StepDefinition(Pattern.compile(regexp), timeoutMillis, body, typeIntrospector));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has moved into the generated code.

} catch (CucumberException e) {
throw e;
} catch (Exception e) {
throw new CucumberException(e);
}
public void addStepDefinition(StepDefinition stepDefinition) {
glue.addStepDefinition(stepDefinition);
}

void addHook(Annotation annotation, Method method) {
if (objectFactory.addClass(method.getDeclaringClass())) {
if (annotation.annotationType().equals(Before.class)) {
String[] tagExpressions = ((Before) annotation).value();
long timeout = ((Before) annotation).timeout();
glue.addBeforeHook(new JavaHookDefinition(method, tagExpressions, ((Before) annotation).order(), timeout, objectFactory));
addBeforeHookDefinition(new JavaHookDefinition(method, tagExpressions, ((Before) annotation).order(), timeout, objectFactory));
} else {
String[] tagExpressions = ((After) annotation).value();
long timeout = ((After) annotation).timeout();
glue.addAfterHook(new JavaHookDefinition(method, tagExpressions, ((After) annotation).order(), timeout, objectFactory));
addAfterHookDefinition(new JavaHookDefinition(method, tagExpressions, ((After) annotation).order(), timeout, objectFactory));
}
}
}

public void addBeforeHookDefinition(String[] tagExpressions, long timeoutMillis, int order, HookBody body) {
glue.addBeforeHook(new Java8HookDefinition(tagExpressions, order, timeoutMillis, body));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has moved into the generated code.

}

public void addAfterHookDefinition(String[] tagExpressions, long timeoutMillis, int order, HookBody body) {
glue.addAfterHook(new Java8HookDefinition(tagExpressions, order, timeoutMillis, body));
}

public void addBeforeHookDefinition(String[] tagExpressions, long timeoutMillis, int order, HookNoArgsBody body) {
glue.addBeforeHook(new Java8HookDefinition(tagExpressions, order, timeoutMillis, body));
public void addBeforeHookDefinition(HookDefinition beforeHook) {
glue.addBeforeHook(beforeHook);
}

public void addAfterHookDefinition(String[] tagExpressions, long timeoutMillis, int order, HookNoArgsBody body) {
glue.addAfterHook(new Java8HookDefinition(tagExpressions, order, timeoutMillis, body));
public void addAfterHookDefinition(HookDefinition afterHook) {
glue.addAfterHook(afterHook);
}

private Pattern pattern(Annotation annotation) throws Throwable {
Expand Down

This file was deleted.

24 changes: 18 additions & 6 deletions java/src/test/java/cucumber/runtime/java/JavaBackendTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,37 @@
import cucumber.runtime.HookDefinition;
import cucumber.runtime.StepDefinition;
import cucumber.runtime.StepDefinitionMatch;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import cucumber.runtime.java.stepdefs.Stepdefs;
import gherkin.pickles.PickleStep;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static java.lang.Thread.currentThread;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;

public class JavaBackendTest {

private ObjectFactory factory;
private JavaBackend backend;

@Before
public void createBackend(){
ClassLoader classLoader = currentThread().getContextClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ResourceLoaderClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
this.factory = new DefaultJavaObjectFactory();
this.backend = new JavaBackend(factory, classFinder);
}

@Test
public void finds_step_definitions_by_classpath_url() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("classpath:cucumber/runtime/java/stepdefs"));
backend.buildWorld();
Expand All @@ -30,8 +46,6 @@ public void finds_step_definitions_by_classpath_url() {

@Test
public void finds_step_definitions_by_package_name() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("cucumber.runtime.java.stepdefs"));
backend.buildWorld();
Expand All @@ -40,8 +54,6 @@ public void finds_step_definitions_by_package_name() {

@Test(expected = CucumberException.class)
public void detects_subclassed_glue_and_throws_exception() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("cucumber.runtime.java.stepdefs", "cucumber.runtime.java.incorrectlysubclassedstepdefs"));
}
Expand Down
25 changes: 19 additions & 6 deletions java/src/test/java/cucumber/runtime/java/JavaHookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.CucumberException;
import cucumber.runtime.Glue;
import cucumber.runtime.HookDefinition;
import cucumber.runtime.RuntimeGlue;
import cucumber.runtime.UndefinedStepsTracker;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import cucumber.runtime.xstream.LocalizedXStreams;
import gherkin.pickles.PickleLocation;
import gherkin.pickles.PickleTag;
Expand Down Expand Up @@ -38,13 +41,23 @@ public class JavaHookTest {
}
}

private final SingletonFactory objectFactory = new SingletonFactory();
private final JavaBackend backend = new JavaBackend(objectFactory);
private final LocalizedXStreams localizedXStreams = new LocalizedXStreams(Thread.currentThread().getContextClassLoader());
private final Glue glue = new RuntimeGlue(localizedXStreams);

private JavaBackend backend;
private Glue glue;
private SingletonFactory objectFactory;

@org.junit.Before
public void loadNoGlue() {
public void createBackendAndLoadNoGlue() {
this.objectFactory = new SingletonFactory();

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
this.backend = new JavaBackend(objectFactory, classFinder);

LocalizedXStreams localizedXStreams = new LocalizedXStreams(classLoader);
this.glue = new RuntimeGlue(localizedXStreams);

backend.loadGlue(glue, Collections.<String>emptyList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@
import cucumber.api.Result;
import cucumber.api.event.EventHandler;
import cucumber.api.event.TestStepFinished;
import cucumber.api.java.ObjectFactory;
import cucumber.api.java.en.Given;
import cucumber.runtime.AmbiguousStepDefinitionsException;
import cucumber.runtime.DuplicateStepDefinitionException;
import cucumber.runtime.Glue;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.io.ClasspathResourceLoader;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import gherkin.events.PickleEvent;
import gherkin.pickles.Argument;
import gherkin.pickles.Pickle;
import gherkin.pickles.PickleLocation;
import gherkin.pickles.PickleStep;
import gherkin.pickles.PickleTag;
import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Collections;

import static java.lang.Thread.currentThread;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand All @@ -43,23 +48,27 @@ public class JavaStepDefinitionTest {
}

private final Defs defs = new Defs();
private final JavaBackend backend = new JavaBackend(new SingletonFactory(defs));
private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
private final RuntimeOptions runtimeOptions = new RuntimeOptions("");
private final Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
private final Glue glue = runtime.getGlue();
private final EventHandler<TestStepFinished> testStepFinishedHandler = new EventHandler<TestStepFinished>() {
@Override
public void receive(TestStepFinished event) {
latestReceivedResult = event.result;
}
};
private JavaBackend backend;
private Runtime runtime;
private Result latestReceivedResult;

@org.junit.Before
public void loadNoGlue() {
backend.loadGlue(glue, Collections.<String>emptyList());
runtime.getEventBus().registerHandlerFor(TestStepFinished.class, testStepFinishedHandler);
@Before
public void createBackendAndLoadNoGlue() {
ClassLoader classLoader = currentThread().getContextClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ResourceLoaderClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
ObjectFactory factory = new SingletonFactory(defs);
this.backend = new JavaBackend(factory, classFinder);
RuntimeOptions runtimeOptions = new RuntimeOptions("");
this.runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);

backend.loadGlue(runtime.getGlue(), Collections.<String>emptyList());
runtime.getEventBus().registerHandlerFor(TestStepFinished.class, new EventHandler<TestStepFinished>() {
@Override
public void receive(TestStepFinished event) {
latestReceivedResult = event.result;
}
});
}

@Test(expected = DuplicateStepDefinitionException.class)
Expand Down
Loading