Polish ControlFlowPointcut[Tests]
This commit is contained in:
parent
66aac7e359
commit
c0f79ca3bf
|
@ -28,8 +28,9 @@ import org.springframework.util.Assert;
|
|||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Pointcut and method matcher for use in simple <b>cflow</b>-style pointcut.
|
||||
* Note that evaluating such pointcuts is 10-15 times slower than evaluating
|
||||
* Pointcut and method matcher for use as a simple <b>cflow</b>-style pointcut.
|
||||
*
|
||||
* <p>Note that evaluating such pointcuts is 10-15 times slower than evaluating
|
||||
* normal pointcuts, but they are useful in some cases.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
|
@ -45,12 +46,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
@Nullable
|
||||
private final String methodName;
|
||||
|
||||
private final AtomicInteger evaluations = new AtomicInteger();
|
||||
private final AtomicInteger evaluationCount = new AtomicInteger();
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new pointcut that matches all control flows below that class.
|
||||
* @param clazz the clazz
|
||||
* Construct a new pointcut that matches all control flows below the given class.
|
||||
* @param clazz the class
|
||||
*/
|
||||
public ControlFlowPointcut(Class<?> clazz) {
|
||||
this(clazz, null);
|
||||
|
@ -58,9 +59,10 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
|
||||
/**
|
||||
* Construct a new pointcut that matches all calls below the given method
|
||||
* in the given class. If no method name is given, matches all control flows
|
||||
* in the given class.
|
||||
* <p>If no method name is given, the pointcut matches all control flows
|
||||
* below the given class.
|
||||
* @param clazz the clazz
|
||||
* @param clazz the class
|
||||
* @param methodName the name of the method (may be {@code null})
|
||||
*/
|
||||
public ControlFlowPointcut(Class<?> clazz, @Nullable String methodName) {
|
||||
|
@ -72,6 +74,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
|
||||
/**
|
||||
* Subclasses can override this for greater filtering (and performance).
|
||||
* <p>The default implementation always returns {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(Class<?> clazz) {
|
||||
|
@ -80,6 +83,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
|
||||
/**
|
||||
* Subclasses can override this if it's possible to filter out some candidate classes.
|
||||
* <p>The default implementation always returns {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
|
@ -93,7 +97,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
this.evaluations.incrementAndGet();
|
||||
this.evaluationCount.incrementAndGet();
|
||||
|
||||
for (StackTraceElement element : new Throwable().getStackTrace()) {
|
||||
if (element.getClassName().equals(this.clazz.getName()) &&
|
||||
|
@ -105,10 +109,12 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
|||
}
|
||||
|
||||
/**
|
||||
* It's useful to know how many times we've fired, for optimization.
|
||||
* Get the number of times {@link #matches(Method, Class, Object...)} has been
|
||||
* evaluated.
|
||||
* <p>Useful for optimization and testing purposes.
|
||||
*/
|
||||
public int getEvaluations() {
|
||||
return this.evaluations.get();
|
||||
return this.evaluationCount.get();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,13 +27,15 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ControlFlowPointcut}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ControlFlowPointcutTests {
|
||||
class ControlFlowPointcutTests {
|
||||
|
||||
@Test
|
||||
public void testMatches() {
|
||||
void matches() {
|
||||
TestBean target = new TestBean();
|
||||
target.setAge(27);
|
||||
NopInterceptor nop = new NopInterceptor();
|
||||
|
@ -45,10 +47,12 @@ public class ControlFlowPointcutTests {
|
|||
// Not advised, not under One
|
||||
assertThat(proxied.getAge()).isEqualTo(target.getAge());
|
||||
assertThat(nop.getCount()).isEqualTo(0);
|
||||
assertThat(cflow.getEvaluations()).isEqualTo(1);
|
||||
|
||||
// Will be advised
|
||||
assertThat(new One().getAge(proxied)).isEqualTo(target.getAge());
|
||||
assertThat(nop.getCount()).isEqualTo(1);
|
||||
assertThat(cflow.getEvaluations()).isEqualTo(2);
|
||||
|
||||
// Won't be advised
|
||||
assertThat(new One().nomatch(proxied)).isEqualTo(target.getAge());
|
||||
|
@ -64,7 +68,7 @@ public class ControlFlowPointcutTests {
|
|||
* expensive.
|
||||
*/
|
||||
@Test
|
||||
public void testSelectiveApplication() {
|
||||
void selectiveApplication() {
|
||||
TestBean target = new TestBean();
|
||||
target.setAge(27);
|
||||
NopInterceptor nop = new NopInterceptor();
|
||||
|
@ -91,24 +95,26 @@ public class ControlFlowPointcutTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsAndHashCode() throws Exception {
|
||||
void equalsAndHashCode() throws Exception {
|
||||
assertThat(new ControlFlowPointcut(One.class)).isEqualTo(new ControlFlowPointcut(One.class));
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge")).isEqualTo(new ControlFlowPointcut(One.class, "getAge"));
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").equals(new ControlFlowPointcut(One.class))).isFalse();
|
||||
assertThat(new ControlFlowPointcut(One.class).hashCode()).isEqualTo(new ControlFlowPointcut(One.class).hashCode());
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isEqualTo(new ControlFlowPointcut(One.class, "getAge").hashCode());
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").hashCode()).isNotEqualTo(new ControlFlowPointcut(One.class).hashCode());
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge")).isNotEqualTo(new ControlFlowPointcut(One.class));
|
||||
|
||||
assertThat(new ControlFlowPointcut(One.class)).hasSameHashCodeAs(new ControlFlowPointcut(One.class));
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge")).hasSameHashCodeAs(new ControlFlowPointcut(One.class, "getAge"));
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge")).doesNotHaveSameHashCodeAs(new ControlFlowPointcut(One.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
assertThat(new ControlFlowPointcut(One.class).toString())
|
||||
void testToString() {
|
||||
assertThat(new ControlFlowPointcut(One.class)).asString()
|
||||
.isEqualTo(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = null");
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge").toString())
|
||||
assertThat(new ControlFlowPointcut(One.class, "getAge")).asString()
|
||||
.isEqualTo(ControlFlowPointcut.class.getName() + ": class = " + One.class.getName() + "; methodName = getAge");
|
||||
}
|
||||
|
||||
public class One {
|
||||
|
||||
private static class One {
|
||||
int getAge(ITestBean proxied) {
|
||||
return proxied.getAge();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue