From b2ce86a5009be3e049dc3213a59f099d6ace1d86 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Fri, 1 Jun 2018 18:02:55 -0700 Subject: [PATCH] Introduce MemoizingRequest --- .../junit/internal/requests/ClassRequest.java | 23 ++------------ .../internal/requests/MemoizingRequest.java | 30 +++++++++++++++++++ .../internal/requests/OrderingRequest.java | 29 ++++++++++++++++++ 3 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/junit/internal/requests/MemoizingRequest.java create mode 100644 src/main/java/org/junit/internal/requests/OrderingRequest.java diff --git a/src/main/java/org/junit/internal/requests/ClassRequest.java b/src/main/java/org/junit/internal/requests/ClassRequest.java index acc9c90aebe9..d60e36062d81 100644 --- a/src/main/java/org/junit/internal/requests/ClassRequest.java +++ b/src/main/java/org/junit/internal/requests/ClassRequest.java @@ -1,17 +1,11 @@ package org.junit.internal.requests; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; import org.junit.internal.builders.SuiteMethodBuilder; -import org.junit.runner.Request; import org.junit.runner.Runner; import org.junit.runners.model.RunnerBuilder; -public class ClassRequest extends Request { - private final Lock runnerLock = new ReentrantLock(); - +public class ClassRequest extends MemoizingRequest { /* * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses * reflection to access this field. See @@ -19,7 +13,6 @@ public class ClassRequest extends Request { */ private final Class fTestClass; private final boolean canUseSuiteMethod; - private volatile Runner runner; public ClassRequest(Class testClass, boolean canUseSuiteMethod) { this.fTestClass = testClass; @@ -31,18 +24,8 @@ public ClassRequest(Class testClass) { } @Override - public Runner getRunner() { - if (runner == null) { - runnerLock.lock(); - try { - if (runner == null) { - runner = new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass); - } - } finally { - runnerLock.unlock(); - } - } - return runner; + protected Runner createRunner() { + return new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass); } private class CustomAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder { diff --git a/src/main/java/org/junit/internal/requests/MemoizingRequest.java b/src/main/java/org/junit/internal/requests/MemoizingRequest.java new file mode 100644 index 000000000000..191c23022536 --- /dev/null +++ b/src/main/java/org/junit/internal/requests/MemoizingRequest.java @@ -0,0 +1,30 @@ +package org.junit.internal.requests; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.junit.runner.Request; +import org.junit.runner.Runner; + +abstract class MemoizingRequest extends Request { + private final Lock runnerLock = new ReentrantLock(); + private volatile Runner runner; + + @Override + public final Runner getRunner() { + if (runner == null) { + runnerLock.lock(); + try { + if (runner == null) { + runner = createRunner(); + } + } finally { + runnerLock.unlock(); + } + } + return runner; + } + + /** Creates the {@link Runner} to return from {@link #getRunner()}. Called at most once. */ + protected abstract Runner createRunner(); +} diff --git a/src/main/java/org/junit/internal/requests/OrderingRequest.java b/src/main/java/org/junit/internal/requests/OrderingRequest.java new file mode 100644 index 000000000000..441e595a3680 --- /dev/null +++ b/src/main/java/org/junit/internal/requests/OrderingRequest.java @@ -0,0 +1,29 @@ +package org.junit.internal.requests; + +import org.junit.internal.runners.ErrorReportingRunner; +import org.junit.runner.Request; +import org.junit.runner.Runner; +import org.junit.runner.manipulation.InvalidOrderingException; +import org.junit.runner.manipulation.Ordering; + +/** @since 4.13 */ +public class OrderingRequest extends MemoizingRequest { + private final Request request; + private final Ordering ordering; + + public OrderingRequest(Request request, Ordering ordering) { + this.request = request; + this.ordering = ordering; + } + + @Override + protected Runner createRunner() { + Runner runner = request.getRunner(); + try { + ordering.apply(runner); + } catch (InvalidOrderingException e) { + return new ErrorReportingRunner(ordering.getClass(), e); + } + return runner; + } +}