• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 package com.google.inject;
19 
20 import static com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
21 import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
22 import static junit.framework.Assert.assertEquals;
23 import static junit.framework.Assert.assertNotNull;
24 import static junit.framework.Assert.assertSame;
25 import static junit.framework.Assert.assertTrue;
26 
27 import com.google.common.base.Function;
28 import com.google.common.base.Joiner;
29 import com.google.common.collect.ImmutableList;
30 import com.google.common.collect.Iterables;
31 import com.google.common.testing.GcFinalization;
32 
33 import junit.framework.Assert;
34 
35 import java.io.ByteArrayInputStream;
36 import java.io.ByteArrayOutputStream;
37 import java.io.IOException;
38 import java.io.NotSerializableException;
39 import java.io.ObjectInputStream;
40 import java.io.ObjectOutputStream;
41 import java.lang.ref.ReferenceQueue;
42 import java.lang.ref.WeakReference;
43 
44 /**
45  * @author jessewilson@google.com (Jesse Wilson)
46  */
47 public class Asserts {
Asserts()48   private Asserts() {}
49 
50   /**
51    * Returns the String that would appear in an error message for this chain of classes
52    * as modules.
53    */
asModuleChain(Class... classes)54   public static String asModuleChain(Class... classes) {
55     return Joiner.on(" -> ").appendTo(new StringBuilder(" (via modules: "),
56         Iterables.transform(ImmutableList.copyOf(classes), new Function<Class, String>() {
57           @Override
58           public String apply(Class input) {
59             return input.getName();
60           }
61         })).append(")").toString();
62   }
63 
64   /**
65    * Returns the source file appears in error messages based on {@link
66    * #getIncludeStackTraceOption()} value.
67    */
68   public static String getDeclaringSourcePart(Class clazz) {
69     if (getIncludeStackTraceOption() == IncludeStackTraceOption.OFF) {
70       return ".configure(Unknown Source";
71     }
72     return ".configure(" + clazz.getSimpleName() + ".java:";
73   }
74 
75   /**
76    * Returns true if {@link #getIncludeStackTraceOption()} returns {@link
77    * IncludeStackTraceOption#OFF}.
78    */
79   public static boolean isIncludeStackTraceOff() {
80     return getIncludeStackTraceOption() == IncludeStackTraceOption.OFF;
81   }
82 
83   /**
84    * Returns true if {@link #getIncludeStackTraceOption()} returns {@link
85    * IncludeStackTraceOption#COMPLETE}.
86    */
87   public static boolean isIncludeStackTraceComplete() {
88     return getIncludeStackTraceOption() == IncludeStackTraceOption.COMPLETE;
89   }
90 
91   /**
92    * Fails unless {@code expected.equals(actual)}, {@code
93    * actual.equals(expected)} and their hash codes are equal. This is useful
94    * for testing the equals method itself.
95    */
96   public static void assertEqualsBothWays(Object expected, Object actual) {
97     assertNotNull(expected);
98     assertNotNull(actual);
99     assertEquals("expected.equals(actual)", actual, expected);
100     assertEquals("actual.equals(expected)", expected, actual);
101     assertEquals("hashCode", expected.hashCode(), actual.hashCode());
102   }
103 
104   /**
105    * Fails unless {@code text} includes all {@code substrings}, in order.
106    */
107   public static void assertContains(String text, String... substrings) {
108     /*if[NO_AOP]
109     // when we strip out bytecode manipulation, we lose the ability to generate some source lines.
110     if (text.contains("(Unknown Source)")) {
111       return;
112     }
113     end[NO_AOP]*/
114 
115     int startingFrom = 0;
116     for (String substring : substrings) {
117       int index = text.indexOf(substring, startingFrom);
118       assertTrue(String.format("Expected \"%s\" to contain substring \"%s\"", text, substring),
119           index >= startingFrom);
120       startingFrom = index + substring.length();
121     }
122 
123     String lastSubstring = substrings[substrings.length - 1];
124     assertTrue(String.format("Expected \"%s\" to contain substring \"%s\" only once),",
125         text, lastSubstring), text.indexOf(lastSubstring, startingFrom) == -1);
126   }
127 
128   /**
129    * Fails unless {@code object} doesn't equal itself when reserialized.
130    */
131   public static void assertEqualWhenReserialized(Object object)
132       throws IOException {
133     Object reserialized = reserialize(object);
134     assertEquals(object, reserialized);
135     assertEquals(object.hashCode(), reserialized.hashCode());
136   }
137 
138   /**
139    * Fails unless {@code object} has the same toString value when reserialized.
140    */
141   public static void assertSimilarWhenReserialized(Object object) throws IOException {
142     Object reserialized = reserialize(object);
143     assertEquals(object.toString(), reserialized.toString());
144   }
145 
146   public static <E> E reserialize(E original) throws IOException {
147     try {
148       ByteArrayOutputStream out = new ByteArrayOutputStream();
149       new ObjectOutputStream(out).writeObject(original);
150       ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
151       @SuppressWarnings("unchecked") // the reserialized type is assignable
152       E reserialized = (E) new ObjectInputStream(in).readObject();
153       return reserialized;
154     } catch (ClassNotFoundException e) {
155       throw new RuntimeException(e);
156     }
157   }
158 
159   public static void assertNotSerializable(Object object) throws IOException {
160     try {
161       reserialize(object);
162       Assert.fail();
163     } catch (NotSerializableException expected) {
164     }
165   }
166 
167   public static void awaitFullGc() {
168     // GcFinalization *should* do it, but doesn't work well in practice...
169     // so we put a second latch and wait for a ReferenceQueue to tell us.
170     ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
171     WeakReference ref = new WeakReference<Object>(new Object(), queue);
172     GcFinalization.awaitFullGc();
173     try {
174       assertSame("queue didn't return ref in time", ref, queue.remove(5000));
175     } catch (IllegalArgumentException e) {
176       throw new RuntimeException(e);
177     } catch (InterruptedException e) {
178       throw new RuntimeException(e);
179     }
180   }
181 
182   public static void awaitClear(WeakReference<?> ref) {
183     // GcFinalization *should* do it, but doesn't work well in practice...
184     // so we put a second latch and wait for a ReferenceQueue to tell us.
185     Object data = ref.get();
186     ReferenceQueue<Object> queue = null;
187     WeakReference extraRef = null;
188     if (data != null) {
189       queue = new ReferenceQueue<Object>();
190       extraRef = new WeakReference<Object>(data, queue);
191       data = null;
192     }
193     GcFinalization.awaitClear(ref);
194     if (queue != null) {
195       try {
196         assertSame("queue didn't return ref in time", extraRef, queue.remove(5000));
197       } catch (IllegalArgumentException e) {
198         throw new RuntimeException(e);
199       } catch (InterruptedException e) {
200         throw new RuntimeException(e);
201       }
202     }
203   }
204 }
205