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

Support @Listeners in annotation transformer #900

Merged
merged 2 commits into from Nov 30, 2015
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/org/testng/IAnnotationTransformer3.java
@@ -0,0 +1,9 @@
package org.testng;

import org.testng.annotations.IListenersAnnotation;

public interface IAnnotationTransformer3 extends IAnnotationTransformer2 {

void transform(IListenersAnnotation annotation, Class testClass);

}
3 changes: 2 additions & 1 deletion src/main/java/org/testng/TestRunner.java
Expand Up @@ -15,6 +15,7 @@
import java.util.concurrent.TimeUnit;

import org.testng.annotations.Guice;
import org.testng.annotations.IListenersAnnotation;
import org.testng.collections.ListMultiMap;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
Expand Down Expand Up @@ -265,7 +266,7 @@ private ListenerHolder findAllListeners(Class<?> cls) {
result.listenerClasses = Lists.newArrayList();

do {
IListeners l = m_annotationFinder.findAnnotation(cls, IListeners.class);
IListenersAnnotation l = m_annotationFinder.findAnnotation(cls, IListenersAnnotation.class);
if (l != null) {
Class<? extends ITestNGListener>[] classes = l.getValue();
for (Class<? extends ITestNGListener> c : classes) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/testng/annotations/IListenersAnnotation.java
@@ -0,0 +1,10 @@
package org.testng.annotations;

import org.testng.ITestNGListener;

public interface IListenersAnnotation extends IAnnotation {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is it necessary to introduce this interface in the hierarchy?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because IListeners is located into the internal package.
There is already some "duplication" between the annotation package and internal.annotation: I've just follow the current pattern :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Should I change something?


Class<? extends ITestNGListener>[] getValue();

void setValue(Class<? extends ITestNGListener>[] value);
}
@@ -1,10 +1,7 @@
package org.testng.internal.annotations;

import org.testng.ITestNGListener;
import org.testng.annotations.IAnnotation;
import org.testng.annotations.IListenersAnnotation;

public interface IListeners extends IAnnotation {
Class<? extends ITestNGListener>[] getValue();
public interface IListeners extends IListenersAnnotation {

void setValue(Class<? extends ITestNGListener>[] value);
}
Expand Up @@ -8,6 +8,7 @@

import org.testng.IAnnotationTransformer;
import org.testng.IAnnotationTransformer2;
import org.testng.IAnnotationTransformer3;
import org.testng.ITestNGMethod;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
Expand All @@ -28,6 +29,7 @@
import org.testng.annotations.IDataProviderAnnotation;
import org.testng.annotations.IExpectedExceptionsAnnotation;
import org.testng.annotations.IFactoryAnnotation;
import org.testng.annotations.IListenersAnnotation;
import org.testng.annotations.IObjectFactoryAnnotation;
import org.testng.annotations.IParametersAnnotation;
import org.testng.annotations.ITestAnnotation;
Expand Down Expand Up @@ -56,13 +58,15 @@ public class JDK15AnnotationFinder implements IAnnotationFinder {
@SuppressWarnings({"deprecation"})
public JDK15AnnotationFinder(IAnnotationTransformer transformer) {
m_transformer = transformer;
m_annotationMap.put(IListenersAnnotation.class, Listeners.class);
m_annotationMap.put(IConfigurationAnnotation.class, Configuration.class);
m_annotationMap.put(IDataProviderAnnotation.class, DataProvider.class);
m_annotationMap.put(IExpectedExceptionsAnnotation.class, ExpectedExceptions.class);
m_annotationMap.put(IFactoryAnnotation.class, Factory.class);
m_annotationMap.put(IObjectFactoryAnnotation.class, ObjectFactory.class);
m_annotationMap.put(IParametersAnnotation.class, Parameters.class);
m_annotationMap.put(ITestAnnotation.class, Test.class);
// internal
m_annotationMap.put(IBeforeSuite.class, BeforeSuite.class);
m_annotationMap.put(IAfterSuite.class, AfterSuite.class);
m_annotationMap.put(IBeforeTest.class, BeforeTest.class);
Expand All @@ -73,7 +77,6 @@ public JDK15AnnotationFinder(IAnnotationTransformer transformer) {
m_annotationMap.put(IAfterGroups.class, AfterGroups.class);
m_annotationMap.put(IBeforeMethod.class, BeforeMethod.class);
m_annotationMap.put(IAfterMethod.class, AfterMethod.class);
m_annotationMap.put(IListeners.class, Listeners.class);
}

private <A extends Annotation> A findAnnotationInSuperClasses(Class<?> cls, Class<A> a) {
Expand Down Expand Up @@ -164,7 +167,18 @@ else if (a instanceof IDataProviderAnnotation) {
else if (a instanceof IFactoryAnnotation) {
transformer2.transform((IFactoryAnnotation) a, testMethod);
}
}

else if (m_transformer instanceof IAnnotationTransformer3) {
IAnnotationTransformer3 transformer = (IAnnotationTransformer3) m_transformer;

//
// Transform @Listeners
//
if (a instanceof IListenersAnnotation) {
transformer.transform((IListenersAnnotation)a, testClass);
}
} // End IAnnotationTransformer3
} // End IAnnotationTransformer2
}

@Override
Expand Down
Expand Up @@ -27,6 +27,7 @@
import org.testng.annotations.IDataProviderAnnotation;
import org.testng.annotations.IExpectedExceptionsAnnotation;
import org.testng.annotations.IFactoryAnnotation;
import org.testng.annotations.IListenersAnnotation;
import org.testng.annotations.IObjectFactoryAnnotation;
import org.testng.annotations.IParametersAnnotation;
import org.testng.annotations.ITestAnnotation;
Expand Down Expand Up @@ -71,7 +72,7 @@ else if (annotationClass == IObjectFactoryAnnotation.class) {
else if (annotationClass == ITestAnnotation.class) {
result = createTestTag(cls, a, transformer);
}
else if (annotationClass == IListeners.class) {
else if (annotationClass == IListenersAnnotation.class) {
result = createListenersTag(cls, a, transformer);
}
else if (annotationClass == IBeforeSuite.class || annotationClass == IAfterSuite.class ||
Expand Down
@@ -1,5 +1,6 @@
package test.annotationtransformer;

import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

/**
Expand All @@ -10,6 +11,7 @@
*
*/
@Test(timeOut = 1000)
@Listeners(MySuiteListener.class)
public class AnnotationTransformerClassSampleTest {

public void one() {
Expand Down
Expand Up @@ -123,6 +123,8 @@ public void verifyAnnotationTransformerClass() {
private void runTest(IAnnotationTransformer transformer,
String passedName, String failedName)
{
MySuiteListener.triggered = false;
MySuiteListener2.triggered = false;
TestNG tng = new TestNG();
tng.setVerbose(0);
if (transformer != null) {
Expand All @@ -140,8 +142,23 @@ private void runTest(IAnnotationTransformer transformer,

Assert.assertEquals(results.size(), 1);
Assert.assertEquals(name, results.get(0).getMethod().getMethodName());
Assert.assertTrue(MySuiteListener.triggered);
Assert.assertFalse(MySuiteListener2.triggered);
}

@Test
public void verifyListenerAnnotationTransformerClass() {
MySuiteListener.triggered = false;
MySuiteListener2.triggered = false;
TestNG tng = new TestNG();
tng.setVerbose(0);
tng.setAnnotationTransformer(new MyListenerTransformer());
tng.setTestClasses(new Class[]{AnnotationTransformerClassSampleTest.class});

tng.run();
Assert.assertFalse(MySuiteListener.triggered);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe you could make the test stronger by actually having the transformer set the listeners to another class and assert that this class was called instead of just testing the original listener wasn't called?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, why not.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Assert.assertTrue(MySuiteListener2.triggered);
}

@Test
public void verifyConfigurationTransformer() {
Expand Down
@@ -0,0 +1,33 @@
package test.annotationtransformer;

import org.testng.IAnnotationTransformer3;
import org.testng.annotations.IConfigurationAnnotation;
import org.testng.annotations.IDataProviderAnnotation;
import org.testng.annotations.IFactoryAnnotation;
import org.testng.annotations.IListenersAnnotation;
import org.testng.annotations.ITestAnnotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class MyListenerTransformer implements IAnnotationTransformer3 {

@Override
public void transform(IListenersAnnotation annotation, Class testClass) {
annotation.setValue(new Class[]{MySuiteListener2.class});
}

@Override
public void transform(IConfigurationAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) {}

@Override
public void transform(IDataProviderAnnotation annotation, Method method) {}

@Override
public void transform(IFactoryAnnotation annotation, Method method) {}

@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor,
Method testMethod) {}
}
17 changes: 17 additions & 0 deletions src/test/java/test/annotationtransformer/MySuiteListener.java
@@ -0,0 +1,17 @@
package test.annotationtransformer;

import org.testng.ISuite;
import org.testng.ISuiteListener;

public class MySuiteListener implements ISuiteListener {

public static boolean triggered = false;

@Override
public void onStart(ISuite suite) {
triggered = true;
}

@Override
public void onFinish(ISuite suite) {}
}
17 changes: 17 additions & 0 deletions src/test/java/test/annotationtransformer/MySuiteListener2.java
@@ -0,0 +1,17 @@
package test.annotationtransformer;

import org.testng.ISuite;
import org.testng.ISuiteListener;

public class MySuiteListener2 implements ISuiteListener {

public static boolean triggered = false;

@Override
public void onStart(ISuite suite) {
triggered = true;
}

@Override
public void onFinish(ISuite suite) {}
}