2 * Copyright (c) 2015 CableLabs and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.packetcable.provider.test.rules;
11 import com.google.common.base.Optional;
12 import java.lang.annotation.ElementType;
13 import java.lang.annotation.Retention;
14 import java.lang.annotation.RetentionPolicy;
15 import java.lang.annotation.Target;
16 import java.util.Arrays;
17 import java.util.List;
18 import java.util.Objects;
19 import org.junit.rules.ErrorCollector;
20 import org.junit.rules.TestRule;
21 import org.junit.runner.Description;
22 import org.junit.runners.model.Statement;
25 * Rule that allows a test to be run with multiple parameters.<br><br>
28 * <li>Individual Method Annotation - {@link Params.UseParams} <br>Used if only a few methods need to use the rule</li>
29 * <li>Class Annotation - {@link Params.AlwaysUseParams} <br> Used if most/all methods will use the rule. Exceptions should be marked with {@link Params.DoNotUseParams}</li>
34 public class Params<T> implements TestRule {
36 private final List<T> allParams;
37 private final VerifiableErrorCollector errorCollector = new VerifiableErrorCollector();
38 private Optional<T> currentParam = null;
42 public static <E> Params<E> of(E... allParams) {
43 return new Params<>(allParams);
46 public static <E extends Enum<E>> Params<E> of(Class<E> enumClass) {
47 return new Params<>(enumClass.getEnumConstants());
50 private Params(List<T> allParams) {
51 this.allParams = allParams;
54 private Params(T[] allParams) {
55 this(Arrays.asList(allParams));
58 public T getCurrentParam() {
59 if (currentParam == null) {
60 throw new IllegalStateException("Params.getCurrentParam called from unannotated method/class");
62 return currentParam.get();
66 public Statement apply(final Statement base, final Description description) {
67 if (!shouldUseParams(description)) {
70 return new Statement() {
73 public void evaluate() throws Throwable {
75 for (final T param : allParams) {
76 currentParam = Optional.of(param);
79 } catch (Throwable t) {
80 errorCollector.addError(new ParamsAssertionError(currentParam.orNull(), t));
84 errorCollector.verify();
89 private boolean shouldUseParams(final Description description) {
90 final UseParams useParamsAnnotation = description.getAnnotation(UseParams.class);
91 boolean testUsesParams = (useParamsAnnotation != null);
92 if (!testUsesParams) {
93 final AlwaysUseParams alwaysUseParams = description.getTestClass().getAnnotation(AlwaysUseParams.class);
94 testUsesParams = (alwaysUseParams != null);
96 testUsesParams = (description.getAnnotation(DoNotUseParams.class) == null);
100 return testUsesParams;
104 * Method will use Params
106 @Retention(RetentionPolicy.RUNTIME)
107 @Target({ElementType.METHOD})
108 public @interface UseParams {
113 * Method will not use Params
115 @Retention(RetentionPolicy.RUNTIME)
116 @Target({ElementType.METHOD})
117 public @interface DoNotUseParams {
122 * All Methods in Class will use Params unless they are annotated with
123 * {@link Params.DoNotUseParams}
125 @Retention(RetentionPolicy.RUNTIME)
126 @Target({ElementType.TYPE})
127 public @interface AlwaysUseParams {
131 public static class ParamsAssertionError extends AssertionError {
132 ParamsAssertionError(Object param, Throwable t) {
133 super(String.format("\nParam: %s\n%s", Objects.toString(param), t));
134 // We don't care where this is thrown from we care about the passed in cause
135 // use its stack trace
136 this.setStackTrace(t.getStackTrace());
142 * ErrorCollector.verify() is protected so extend ErrorCollector so we can call it.
144 private class VerifiableErrorCollector extends ErrorCollector {
145 public void verify() throws Throwable {