| /* |
| * Copyright (c) 2014 Google, Inc. |
| * |
| * 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.common.truth; |
| |
| import com.google.common.base.Throwables; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| import java.util.regex.Pattern; |
| import org.junit.ComparisonFailure; |
| import org.junit.rules.TestRule; |
| |
| /** |
| * Extracted routines that need to be swapped in for GWT, to allow for minimal deltas between the |
| * GWT and non-GWT version. |
| * |
| * @author Christian Gruber (cgruber@google.com) |
| */ |
| final class Platform { |
| private Platform() {} |
| |
| /** Returns true if the instance is assignable to the type Clazz. */ |
| static boolean isInstanceOfType(Object instance, Class<?> clazz) { |
| return isInstanceOfTypeJava(instance, clazz); |
| } |
| |
| /** |
| * Returns true if the instance is assignable to the type Clazz (suitable for a JVM environment). |
| */ |
| static boolean isInstanceOfTypeJava(Object instance, Class<?> clazz) { |
| return clazz.isInstance(instance); |
| } |
| |
| /** |
| * Returns true if the instance is assignable to the type Clazz (suitable for a GWT environment). |
| */ |
| static boolean isInstanceOfTypeGWT(Object instance, Class<?> clazz) { |
| String className = clazz.getName(); |
| Set<String> types = new LinkedHashSet<>(); |
| types.add(instance.getClass().getCanonicalName()); |
| addTypeNames(instance.getClass(), types); |
| return types.contains(className); |
| } |
| |
| private static void addInterfaceNames(Class<?>[] interfaces, Set<String> types) { |
| for (Class<?> interfaze : interfaces) { |
| types.add(interfaze.getName()); |
| addInterfaceNames(interfaze.getInterfaces(), types); |
| } |
| } |
| |
| private static void addTypeNames(Class<?> clazz, Set<String> types) { |
| for (Class<?> current = clazz; current != null; current = current.getSuperclass()) { |
| types.add(current.getName()); |
| addInterfaceNames(current.getInterfaces(), types); |
| } |
| } |
| |
| static AssertionError comparisonFailure( |
| String message, String expected, String actual, Throwable cause) { |
| return new ComparisonFailureWithCause(message, expected, actual, cause); |
| } |
| |
| /** Determines if the given subject contains a match for the given regex. */ |
| static boolean containsMatch(String actual, String regex) { |
| return Pattern.compile(regex).matcher(actual).find(); |
| } |
| |
| /** |
| * Returns an array containing all of the exceptions that were suppressed to deliver the given |
| * exception. If suppressed exceptions are not supported (pre-Java 1.7), an empty array will be |
| * returned. |
| */ |
| static Throwable[] getSuppressed(Throwable throwable) { |
| try { |
| Method getSuppressed = throwable.getClass().getMethod("getSuppressed"); |
| return (Throwable[]) getSuppressed.invoke(throwable); |
| } catch (NoSuchMethodException e) { |
| return new Throwable[0]; |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } catch (InvocationTargetException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Returns true if stack trace cleaning is explicitly disabled in a system property. This switch |
| * os intended to be used when attempting to debug the frameworks which are collapsed or filtered |
| * out of stack traces by the cleaner. |
| */ |
| static boolean isStackTraceCleaningDisabled() { |
| return Boolean.parseBoolean( |
| System.getProperty("com.google.common.truth.disable_stack_trace_cleaning")); |
| } |
| |
| private static final class ComparisonFailureWithCause extends ComparisonFailure { |
| /** Separate cause field, in case initCause() fails. */ |
| private final Throwable cause; |
| |
| ComparisonFailureWithCause(String message, String expected, String actual, Throwable cause) { |
| super(message, expected, actual); |
| this.cause = cause; |
| |
| try { |
| initCause(cause); |
| } catch (IllegalStateException alreadyInitializedBecauseOfHarmonyBug) { |
| // See Truth.AssertionErrorWithCause. |
| } |
| } |
| |
| @Override |
| @SuppressWarnings("UnsynchronizedOverridesSynchronized") |
| public Throwable getCause() { |
| return cause; |
| } |
| |
| @Override |
| public String toString() { |
| return getLocalizedMessage(); |
| } |
| } |
| |
| static String doubleToString(double value) { |
| return Double.toString(value); |
| } |
| |
| static String floatToString(float value) { |
| return Float.toString(value); |
| } |
| |
| /** Returns a human readable string representation of the throwable's stack trace. */ |
| static String getStackTraceAsString(Throwable throwable) { |
| return Throwables.getStackTraceAsString(throwable); |
| } |
| |
| /** Tests if current platform is Android. */ |
| static boolean isAndroid() { |
| return System.getProperties().getProperty("java.runtime.name").contains("Android"); |
| } |
| |
| /** |
| * Wrapping interface of {@link TestRule} to be used within truth. |
| * |
| * <p>Note that the sole purpose of this interface is to allow it to be swapped in GWT |
| * implementation. |
| */ |
| interface JUnitTestRule extends TestRule {} |
| } |