Skip to content

Commit 97280a5

Browse files
authored
Replace more reflection with byte code transforms (#120)
1 parent 7a5ab20 commit 97280a5

File tree

9 files changed

+162
-212
lines changed

9 files changed

+162
-212
lines changed

src/main/java/com/nordstrom/automation/junit/AtomicTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.nordstrom.automation.junit;
22

3-
import static com.nordstrom.automation.junit.LifecycleHooks.invoke;
4-
53
import java.lang.annotation.Annotation;
64
import java.util.ArrayList;
75
import java.util.Arrays;

src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ static void releaseMappingsFor(EachTestNotifier notifier) {
191191
ArtifactCollector.releaseWatchersOf(description);
192192
CreateTest.releaseMappingsFor(atomicTest.getRunner(), atomicTest.getIdentity(), target);
193193
GetAnnotations.releaseAnnotationsFor(atomicTest.getIdentity());
194+
TestMethodDescription.releaseDescriptionFor(atomicTest.getIdentity());
194195
}
195196

196197
/**
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.nordstrom.automation.junit;
2+
3+
import java.lang.annotation.Annotation;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.junit.runners.model.FrameworkField;
8+
9+
/**
10+
* This interface declares an accessor method for the [ {@code Class<Annotation>} &rarr; {@code List<FrameworkField>} ]
11+
* map of {@code org.junit.runners.model.TestClass}.
12+
*/
13+
public interface FieldsForAnnotationsAccessor {
14+
15+
/**
16+
* Get the map that associates annotation types with the fields to which they're attached.
17+
*
18+
* @return mappings from annotation types to lists of annotated fields
19+
*/
20+
Map<Class<? extends Annotation>, List<FrameworkField>> getFieldsForAnnotations();
21+
22+
}

src/main/java/com/nordstrom/automation/junit/JUnitAgent.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class JUnitAgent {
4444
* <ul>
4545
* <li>{@code org.junit.runner.Description}</li>
4646
* <li>{@code org.junit.runners.model.FrameworkMethod}</li>
47+
* <li>{@code org.junit.runners.model.TestClass}</li>
4748
* <li>{@code org.junit.internal.runners.model.EachTestNotifier}</li>
4849
* <li>{@code org.junit.internal.runners.model.ReflectiveCallable}</li>
4950
* <li>{@code org.junit.runners.model.RunnerScheduler}</li>
@@ -52,7 +53,7 @@ public class JUnitAgent {
5253
* <li>{@code org.junit.experimental.theories.Theories$TheoryAnchor}</li>
5354
* <li>{@code org.junit.runner.notification.RunNotifier}</li>
5455
* <li>{@code junitparams.internal.ParameterisedTestMethodRunner}</li>
55-
* <li>{@code junitparams.internal.ParametrizedDescription}</li>
56+
* <li>{@code junitparams.internal.TestMethod}</li>
5657
* </ul>
5758
*
5859
* @param agentArgs agent options
@@ -110,8 +111,8 @@ public static ClassFileTransformer installTransformer(Instrumentation instrument
110111
final TypeDescription runWithCompleteAssignment = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.RunWithCompleteAssignment").resolve();
111112
// junitparams.internal.ParameterisedTestMethodRunner
112113
final TypeDescription nextCount = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.NextCount").resolve();
113-
// junitparams.internal.ParametrizedDescription
114-
final TypeDescription parameterizedDescription = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.ParameterizedDescription").resolve();
114+
// junitparams.internal.TestMethod
115+
final TypeDescription testMethodDescription = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.TestMethodDescription").resolve();
115116

116117
return new AgentBuilder.Default()
117118
.type(hasSuperType(named("org.junit.runner.Description")))
@@ -136,6 +137,15 @@ public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDesc
136137
.implement(Hooked.class);
137138
}
138139
})
140+
.type(hasSuperType(named("org.junit.runners.model.TestClass")))
141+
.transform(new Transformer() {
142+
@Override
143+
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
144+
ClassLoader classLoader, JavaModule module) {
145+
return builder.implement(FieldsForAnnotationsAccessor.class).intercept(FieldAccessor.ofField("fieldsForAnnotations"))
146+
.implement(Hooked.class);
147+
}
148+
})
139149
.type(hasSuperType(named("org.junit.internal.runners.model.EachTestNotifier")))
140150
.transform(new Transformer() {
141151
@Override
@@ -208,15 +218,16 @@ public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDesc
208218
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription type,
209219
ClassLoader classloader, JavaModule module) {
210220
return builder.method(named("nextCount")).intercept(MethodDelegation.to(nextCount))
221+
.implement(MethodAccessor.class).intercept(FieldAccessor.ofField("method"))
211222
.implement(Hooked.class);
212223
}
213224
})
214-
.type(hasSuperType(named("junitparams.internal.ParametrizedDescription")))
225+
.type(hasSuperType(named("junitparams.internal.TestMethod")))
215226
.transform(new Transformer() {
216227
@Override
217228
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription type,
218229
ClassLoader classloader, JavaModule module) {
219-
return builder.method(named("parametrizedDescription")).intercept(MethodDelegation.to(parameterizedDescription))
230+
return builder.method(named("description")).intercept(MethodDelegation.to(testMethodDescription))
220231
.implement(Hooked.class);
221232
}
222233
})
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.nordstrom.automation.junit;
2+
3+
import junitparams.internal.TestMethod;
4+
5+
/**
6+
* This interface declares an accessor for the [method] field of {@code junitparams.internal.ParameterisedTestMethodRunner}.
7+
*/
8+
public interface MethodAccessor {
9+
10+
/**
11+
* Get the JUnitParams test method of this parameterized runner.
12+
*
13+
* @return {@link TestMethod} assigned to this runner
14+
*/
15+
TestMethod getMethod();
16+
17+
}

src/main/java/com/nordstrom/automation/junit/NextCount.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package com.nordstrom.automation.junit;
22

3-
import static com.nordstrom.automation.junit.LifecycleHooks.getFieldValue;
4-
import static com.nordstrom.automation.junit.LifecycleHooks.invoke;
5-
63
import java.util.concurrent.Callable;
74

85
import junitparams.internal.ParameterisedTestMethodRunner;
@@ -31,11 +28,11 @@ public static int intercept(
3128
@This final ParameterisedTestMethodRunner runner, @SuperCall final Callable<?> proxy) throws Exception {
3229

3330
// get reference to JUnitParams target test method
34-
TestMethod method = getFieldValue(runner, "method");
31+
TestMethod method = ((MethodAccessor) runner).getMethod();
3532
// if this method is being retried
3633
if (RetryHandler.doRetryFor(method.frameworkMethod())) {
3734
// get current parameter set index
38-
int nextCount = invoke(runner, "count");
35+
int nextCount = LifecycleHooks.invoke(runner, "count");
3936
// return prior index
4037
return nextCount - 1;
4138
// otherwise

src/main/java/com/nordstrom/automation/junit/ParameterizedDescription.java

Lines changed: 0 additions & 176 deletions
This file was deleted.

0 commit comments

Comments
 (0)