// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.testutil;

/** Static JUnit utility methods. */
public class GerritJUnit {
  /**
   * Assert that an exception is thrown by a block of code.
   *
   * <p>This method is source-compatible with <a
   * href="https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThrows(java.lang.Class,%20org.junit.function.ThrowingRunnable)">JUnit
   * 4.13 beta</a>.
   *
   * <p>This construction is recommended by the Truth team for use in conjunction with asserting
   * over a {@code ThrowableSubject} on the return type:
   *
   * <pre>
   *   MyException e = assertThrows(MyException.class, () -> doSomething(foo));
   *   assertThat(e).isInstanceOf(MySubException.class);
   *   assertThat(e).hasMessageThat().contains("sub-exception occurred");
   * </pre>
   *
   * @param throwableClass expected exception type.
   * @param runnable runnable containing arbitrary code.
   * @return exception that was thrown.
   */
  public static <T extends Throwable> T assertThrows(
      Class<T> throwableClass, ThrowingRunnable runnable) {
    try {
      runnable.run();
    } catch (Throwable t) {
      if (!throwableClass.isInstance(t)) {
        throw new AssertionError(
            "expected "
                + throwableClass.getName()
                + " but "
                + t.getClass().getName()
                + " was thrown",
            t);
      }
      @SuppressWarnings("unchecked")
      T toReturn = (T) t;
      return toReturn;
    }
    throw new AssertionError(
        "expected " + throwableClass.getName() + " but no exception was thrown");
  }

  @FunctionalInterface
  public interface ThrowingRunnable {
    void run() throws Throwable;
  }

  private GerritJUnit() {}
}
