Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Issue #186. Making sure that Stepdef class is registered with ObjectF…

…actory not a superclass when superclass declares anotated methods
  • Loading branch information...
commit fdc60bcefa1bf213350fc6e5e12269c7961b19fc 1 parent 0d87921
@vasiliygagin authored
View
15 java/src/main/java/cucumber/runtime/java/ClasspathMethodScanner.java
@@ -4,9 +4,11 @@
import cucumber.annotation.Before;
import cucumber.annotation.Order;
import cucumber.io.ClasspathResourceLoader;
+import cucumber.runtime.Utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.List;
@@ -23,8 +25,12 @@ public void scan(JavaBackend javaBackend, List<String> gluePaths) {
for (String gluePath : gluePaths) {
String packageName = gluePath.replace('/', '.').replace('\\', '.'); // Sometimes the gluePath will be a path, not a package
for (Class<?> candidateClass : resourceLoader.getDescendants(Object.class, packageName)) {
+ while (candidateClass != Object.class && !Utils.isInstantiable(candidateClass)) {
+ // those can't be instantiated without container class present.
+ candidateClass = candidateClass.getSuperclass();
+ }
for (Method method : candidateClass.getMethods()) {
- scan(method, cucumberAnnotationClasses, javaBackend);
+ scan(candidateClass, method, cucumberAnnotationClasses, javaBackend);
}
}
}
@@ -34,14 +40,15 @@ public void scan(JavaBackend javaBackend, List<String> gluePaths) {
return resourceLoader.getAnnotations("cucumber.annotation");
}
- private void scan(Method method, Collection<Class<? extends Annotation>> cucumberAnnotationClasses, JavaBackend javaBackend) {
+ private void scan(Class<?> candidateClass, Method method, Collection<Class<? extends Annotation>> cucumberAnnotationClasses,
+ JavaBackend javaBackend) {
for (Class<? extends Annotation> cucumberAnnotationClass : cucumberAnnotationClasses) {
Annotation annotation = method.getAnnotation(cucumberAnnotationClass);
if (annotation != null && !annotation.annotationType().equals(Order.class)) {
if (isHookAnnotation(annotation)) {
- javaBackend.addHook(annotation, method);
+ javaBackend.addHook(annotation, candidateClass, method);
} else if (isStepdefAnnotation(annotation)) {
- javaBackend.addStepDefinition(annotation, method);
+ javaBackend.addStepDefinition(annotation, candidateClass, method);
}
}
}
View
10 java/src/main/java/cucumber/runtime/java/JavaBackend.java
@@ -78,14 +78,13 @@ public String getSnippet(Step step) {
return snippetGenerator.getSnippet(step);
}
- void addStepDefinition(Annotation annotation, Method method) {
+ void addStepDefinition(Annotation annotation, Class<?> candidateClass, Method method) {
try {
Method regexpMethod = annotation.getClass().getMethod("value");
String regexpString = (String) regexpMethod.invoke(annotation);
if (regexpString != null) {
Pattern pattern = Pattern.compile(regexpString);
- Class<?> clazz = method.getDeclaringClass();
- objectFactory.addClass(clazz);
+ objectFactory.addClass(candidateClass);
glue.addStepDefinition(new JavaStepDefinition(method, pattern, objectFactory));
}
} catch (NoSuchMethodException e) {
@@ -97,9 +96,8 @@ void addStepDefinition(Annotation annotation, Method method) {
}
}
- void addHook(Annotation annotation, Method method) {
- Class<?> clazz = method.getDeclaringClass();
- objectFactory.addClass(clazz);
+ void addHook(Annotation annotation, Class<?> candidateClass, Method method) {
+ objectFactory.addClass(candidateClass);
Order order = method.getAnnotation(Order.class);
int hookOrder = (order == null) ? Integer.MAX_VALUE : order.value();
View
41 java/src/test/java/cucumber/runtime/java/ClasspathMethodScannerTest.java
@@ -0,0 +1,41 @@
+package cucumber.runtime.java;
+
+import static java.util.Arrays.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import cucumber.annotation.Before;
+import cucumber.io.ClasspathResourceLoader;
+import cucumber.runtime.Glue;
+import cucumber.runtime.java.test2.Stepdefs2;
+
+public class ClasspathMethodScannerTest {
+
+ @Test
+ public void loadGlue_should_not_try_to_instantiate_super_classes() {
+
+ ClasspathMethodScanner classpathMethodScanner = new ClasspathMethodScanner(new ClasspathResourceLoader(Thread.currentThread()
+ .getContextClassLoader()));
+
+ ObjectFactory factory = Mockito.mock(ObjectFactory.class);
+ Glue world = Mockito.mock(Glue.class);
+ JavaBackend backend = new JavaBackend(factory);
+ Whitebox.setInternalState(backend, "glue", world);
+
+ // this delegates to classpathMethodScanner.scan which we test
+ classpathMethodScanner.scan(backend, asList("cucumber/runtime/java/test2"));
+
+ verify(factory, times(1)).addClass(Stepdefs2.class);
+ verifyNoMoreInteractions(factory);
+ }
+
+ public static class BaseStepDefs {
+
+ @Before
+ public void m() {
+ }
+ }
+}
View
12 java/src/test/java/cucumber/runtime/java/JavaHookTest.java
@@ -44,7 +44,7 @@ public void loadNoGlue() {
@Test
public void before_hooks_get_registered() throws Exception {
backend.buildWorld();
- backend.addHook(BEFORE.getAnnotation(Before.class), BEFORE);
+ backend.addHook(BEFORE.getAnnotation(Before.class), HasHooks.class, BEFORE);
JavaHookDefinition hookDef = (JavaHookDefinition) glue.getBeforeHooks().get(0);
assertEquals(0, glue.getAfterHooks().size());
assertEquals(BEFORE, hookDef.getMethod());
@@ -53,7 +53,7 @@ public void before_hooks_get_registered() throws Exception {
@Test
public void after_hooks_get_registered() throws Exception {
backend.buildWorld();
- backend.addHook(AFTER.getAnnotation(After.class), AFTER);
+ backend.addHook(AFTER.getAnnotation(After.class), HasHooks.class, AFTER);
JavaHookDefinition hookDef = (JavaHookDefinition) glue.getAfterHooks().get(0);
assertEquals(0, glue.getBeforeHooks().size());
assertEquals(AFTER, hookDef.getMethod());
@@ -62,7 +62,7 @@ public void after_hooks_get_registered() throws Exception {
@Test
public void hook_order_gets_registered() {
backend.buildWorld();
- backend.addHook(AFTER.getAnnotation(After.class), AFTER);
+ backend.addHook(AFTER.getAnnotation(After.class), HasHooks.class, AFTER);
HookDefinition hookDef = glue.getAfterHooks().get(0);
assertEquals(1, hookDef.getOrder());
}
@@ -70,7 +70,7 @@ public void hook_order_gets_registered() {
@Test
public void hook_with_no_order_is_last() {
backend.buildWorld();
- backend.addHook(BEFORE.getAnnotation(Before.class), BEFORE);
+ backend.addHook(BEFORE.getAnnotation(Before.class), HasHooks.class, BEFORE);
HookDefinition hookDef = glue.getBeforeHooks().get(0);
assertEquals(Integer.MAX_VALUE, hookDef.getOrder());
}
@@ -78,7 +78,7 @@ public void hook_with_no_order_is_last() {
@Test
public void matches_matching_tags() {
backend.buildWorld();
- backend.addHook(BEFORE.getAnnotation(Before.class), BEFORE);
+ backend.addHook(BEFORE.getAnnotation(Before.class), HasHooks.class, BEFORE);
HookDefinition before = glue.getBeforeHooks().get(0);
assertTrue(before.matches(asList("@bar", "@zap")));
}
@@ -86,7 +86,7 @@ public void matches_matching_tags() {
@Test
public void does_not_match_non_matching_tags() {
backend.buildWorld();
- backend.addHook(BEFORE.getAnnotation(Before.class), BEFORE);
+ backend.addHook(BEFORE.getAnnotation(Before.class), HasHooks.class, BEFORE);
HookDefinition before = glue.getBeforeHooks().get(0);
assertFalse(before.matches(asList("@bar")));
}
View
26 java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java
@@ -1,15 +1,12 @@
package cucumber.runtime.java;
-import cucumber.annotation.en.Given;
-import cucumber.io.ClasspathResourceLoader;
-import cucumber.runtime.AmbiguousStepDefinitionsException;
-import cucumber.runtime.Glue;
-import cucumber.runtime.Runtime;
+import static java.util.Arrays.*;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
import gherkin.I18n;
import gherkin.formatter.Reporter;
import gherkin.formatter.model.Comment;
import gherkin.formatter.model.Step;
-import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Collections;
@@ -17,10 +14,13 @@
import java.util.List;
import java.util.Set;
-import static java.util.Arrays.asList;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
+import org.junit.Test;
+
+import cucumber.annotation.en.Given;
+import cucumber.io.ClasspathResourceLoader;
+import cucumber.runtime.AmbiguousStepDefinitionsException;
+import cucumber.runtime.Glue;
+import cucumber.runtime.Runtime;
public class JavaStepDefinitionTest {
@@ -52,8 +52,8 @@ public void loadNoGlue() {
@Test(expected = AmbiguousStepDefinitionsException.class)
public void throws_ambiguous_when_two_matches_are_found() throws Throwable {
- backend.addStepDefinition(FOO.getAnnotation(Given.class), FOO);
- backend.addStepDefinition(BAR.getAnnotation(Given.class), BAR);
+ backend.addStepDefinition(FOO.getAnnotation(Given.class), Defs.class, FOO);
+ backend.addStepDefinition(BAR.getAnnotation(Given.class), Defs.class, BAR);
Reporter reporter = mock(Reporter.class);
runtime.buildBackendWorlds();
@@ -63,7 +63,7 @@ public void throws_ambiguous_when_two_matches_are_found() throws Throwable {
@Test
public void does_not_throw_ambiguous_when_nothing_is_ambiguous() throws Throwable {
- backend.addStepDefinition(FOO.getAnnotation(Given.class), FOO);
+ backend.addStepDefinition(FOO.getAnnotation(Given.class), Defs.class, FOO);
Reporter reporter = mock(Reporter.class);
runtime.buildBackendWorlds();
View
6 java/src/test/java/cucumber/runtime/java/test2/Stepdefs2.java
@@ -0,0 +1,6 @@
+package cucumber.runtime.java.test2;
+
+import cucumber.runtime.java.ClasspathMethodScannerTest;
+
+public class Stepdefs2 extends ClasspathMethodScannerTest.BaseStepDefs {
+}
Please sign in to comment.
Something went wrong with that request. Please try again.