mirror of
https://github.com/google/guice.git
synced 2024-04-21 12:32:36 +00:00
Changes include: - update Guice tests that asserts error messages - export new errors tests - update Guice compiler flag so parameter names are available at runtime, which is required for the errors tests PiperOrigin-RevId: 337602195
234 lines
8.5 KiB
Java
234 lines
8.5 KiB
Java
/*
|
|
* Copyright (C) 2008 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.inject;
|
|
|
|
import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH;
|
|
import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
|
|
import static junit.framework.Assert.assertEquals;
|
|
import static junit.framework.Assert.assertNotNull;
|
|
import static junit.framework.Assert.assertSame;
|
|
import static junit.framework.Assert.assertTrue;
|
|
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Iterables;
|
|
import com.google.common.testing.GcFinalization;
|
|
import com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.NotSerializableException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.ObjectOutputStream;
|
|
import java.lang.ref.ReferenceQueue;
|
|
import java.lang.ref.WeakReference;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.net.URLClassLoader;
|
|
import junit.framework.Assert;
|
|
|
|
/** @author jessewilson@google.com (Jesse Wilson) */
|
|
public class Asserts {
|
|
|
|
private Asserts() {}
|
|
|
|
/**
|
|
* Returns the String that would appear in an error message for this chain of classes as modules.
|
|
*/
|
|
public static String asModuleChain(Class<?>... classes) {
|
|
return Joiner.on(" -> ")
|
|
.appendTo(
|
|
new StringBuilder(" (via modules: "),
|
|
Iterables.transform(ImmutableList.copyOf(classes), Class::getName))
|
|
.append(")")
|
|
.toString();
|
|
}
|
|
|
|
/**
|
|
* Returns the source file appears in error messages based on {@link
|
|
* #getIncludeStackTraceOption()} value.
|
|
*/
|
|
public static String getDeclaringSourcePart(Class<?> clazz) {
|
|
if (getIncludeStackTraceOption() == IncludeStackTraceOption.OFF) {
|
|
return ".configure(Unknown Source";
|
|
}
|
|
return ".configure(" + clazz.getSimpleName() + ".java:";
|
|
}
|
|
|
|
/**
|
|
* Returns true if {@link #getIncludeStackTraceOption()} returns {@link
|
|
* IncludeStackTraceOption#OFF}.
|
|
*/
|
|
public static boolean isIncludeStackTraceOff() {
|
|
return getIncludeStackTraceOption() == IncludeStackTraceOption.OFF;
|
|
}
|
|
|
|
/**
|
|
* Returns true if {@link #getIncludeStackTraceOption()} returns {@link
|
|
* IncludeStackTraceOption#COMPLETE}.
|
|
*/
|
|
public static boolean isIncludeStackTraceComplete() {
|
|
return getIncludeStackTraceOption() == IncludeStackTraceOption.COMPLETE;
|
|
}
|
|
|
|
/**
|
|
* Fails unless {@code expected.equals(actual)}, {@code actual.equals(expected)} and their hash
|
|
* codes are equal. This is useful for testing the equals method itself.
|
|
*/
|
|
public static void assertEqualsBothWays(Object expected, Object actual) {
|
|
assertNotNull(expected);
|
|
assertNotNull(actual);
|
|
assertEquals("expected.equals(actual)", actual, expected);
|
|
assertEquals("actual.equals(expected)", expected, actual);
|
|
assertEquals("hashCode", expected.hashCode(), actual.hashCode());
|
|
}
|
|
|
|
/** Fails unless {@code text} includes all {@code substrings}, in order, no duplicates */
|
|
public static void assertContains(String text, String... substrings) {
|
|
assertContains(text, false, substrings);
|
|
}
|
|
|
|
/**
|
|
* Fails unless {@code text} includes all {@code substrings}, in order, and optionally {@code
|
|
* allowDuplicates}.
|
|
*/
|
|
public static void assertContains(String text, boolean allowDuplicates, String... substrings) {
|
|
/*if[NO_AOP]
|
|
// when we strip out bytecode manipulation, we lose the ability to generate some source lines.
|
|
if (text.contains("(Unknown Source)")) {
|
|
return;
|
|
}
|
|
end[NO_AOP]*/
|
|
|
|
int startingFrom = 0;
|
|
for (String substring : substrings) {
|
|
int index = text.indexOf(substring, startingFrom);
|
|
assertTrue(
|
|
String.format("Expected \"%s\" to contain substring \"%s\"", text, substring),
|
|
index >= startingFrom);
|
|
startingFrom = index + substring.length();
|
|
}
|
|
|
|
if (!allowDuplicates) {
|
|
String lastSubstring = substrings[substrings.length - 1];
|
|
assertTrue(
|
|
String.format(
|
|
"Expected \"%s\" to contain substring \"%s\" only once),", text, lastSubstring),
|
|
text.indexOf(lastSubstring, startingFrom) == -1);
|
|
}
|
|
}
|
|
|
|
/** Fails unless {@code object} doesn't equal itself when reserialized. */
|
|
public static void assertEqualWhenReserialized(Object object) throws IOException {
|
|
Object reserialized = reserialize(object);
|
|
assertEquals(object, reserialized);
|
|
assertEquals(object.hashCode(), reserialized.hashCode());
|
|
}
|
|
|
|
/** Fails unless {@code object} has the same toString value when reserialized. */
|
|
public static void assertSimilarWhenReserialized(Object object) throws IOException {
|
|
Object reserialized = reserialize(object);
|
|
assertThat(reserialized.toString()).isEqualTo(object.toString());
|
|
}
|
|
|
|
public static <E> E reserialize(E original) throws IOException {
|
|
try {
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
new ObjectOutputStream(out).writeObject(original);
|
|
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
|
@SuppressWarnings("unchecked") // the reserialized type is assignable
|
|
E reserialized = (E) new ObjectInputStream(in).readObject();
|
|
return reserialized;
|
|
} catch (ClassNotFoundException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
public static void assertNotSerializable(Object object) throws IOException {
|
|
try {
|
|
reserialize(object);
|
|
Assert.fail();
|
|
} catch (NotSerializableException expected) {
|
|
}
|
|
}
|
|
|
|
public static void awaitFullGc() {
|
|
// GcFinalization *should* do it, but doesn't work well in practice...
|
|
// so we put a second latch and wait for a ReferenceQueue to tell us.
|
|
ReferenceQueue<Object> queue = new ReferenceQueue<>();
|
|
WeakReference<Object> ref = new WeakReference<>(new Object(), queue);
|
|
GcFinalization.awaitFullGc();
|
|
try {
|
|
assertSame("queue didn't return ref in time", ref, queue.remove(5000));
|
|
} catch (IllegalArgumentException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InterruptedException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
public static void awaitClear(WeakReference<?> ref) {
|
|
// GcFinalization *should* do it, but doesn't work well in practice...
|
|
// so we put a second latch and wait for a ReferenceQueue to tell us.
|
|
Object data = ref.get();
|
|
ReferenceQueue<Object> queue = null;
|
|
WeakReference<Object> extraRef = null;
|
|
if (data != null) {
|
|
queue = new ReferenceQueue<>();
|
|
extraRef = new WeakReference<>(data, queue);
|
|
data = null;
|
|
}
|
|
GcFinalization.awaitClear(ref);
|
|
if (queue != null) {
|
|
try {
|
|
assertSame("queue didn't return ref in time", extraRef, queue.remove(5000));
|
|
} catch (IllegalArgumentException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InterruptedException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Returns the URLs in the system class path. */
|
|
// TODO(user): Use a common API once that's available.
|
|
public static URL[] getClassPathUrls() {
|
|
if (Asserts.class.getClassLoader() instanceof URLClassLoader) {
|
|
return ((URLClassLoader) Asserts.class.getClassLoader()).getURLs();
|
|
}
|
|
ImmutableList.Builder<URL> urls = ImmutableList.builder();
|
|
for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
|
|
try {
|
|
try {
|
|
urls.add(new File(entry).toURI().toURL());
|
|
} catch (SecurityException e) { // File.toURI checks to see if the file is a directory
|
|
urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
|
|
}
|
|
} catch (MalformedURLException e) {
|
|
AssertionError error = new AssertionError("malformed class path entry: " + entry);
|
|
error.initCause(e);
|
|
throw error;
|
|
}
|
|
}
|
|
return urls.build().toArray(new URL[0]);
|
|
}
|
|
}
|