001 /*
002 * Created on May 21, 2007
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2007-2011 the original author or authors.
015 */
016 package org.fest.assertions;
017
018 import static org.fest.assertions.ErrorMessages.*;
019 import static org.fest.assertions.Fail.*;
020 import static org.fest.assertions.Formatting.format;
021 import static org.fest.util.Collections.list;
022 import static org.fest.util.Objects.areEqual;
023
024 import java.util.Collection;
025
026 /**
027 * Template for assertions.
028 * @param <S> used to simulate "self types." For more information please read "<a
029 * href="http://passion.forco.de/content/emulating-self-types-using-java-generics-simplify-fluent-api-implementation"
030 * target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>."
031 * @param <A> the type the "actual" value.
032 *
033 * @author Yvonne Wang
034 * @author Alex Ruiz
035 */
036 public abstract class GenericAssert<S, A> extends Assert {
037
038 protected final A actual;
039 protected final S myself;
040
041 /**
042 * Creates a new <code>{@link GenericAssert}</code>.
043 * @param selfType the "self type."
044 * @param actual the actual value to verify.
045 */
046 protected GenericAssert(Class<S> selfType, A actual) {
047 this.actual = actual;
048 myself = selfType.cast(this);
049 }
050
051 /**
052 * Asserts that the actual value (specified in the constructor of this class) is {@code null}.
053 * @throws AssertionError if the actual value is not {@code null}.
054 */
055 public final void isNull() {
056 failIfNotNull(customErrorMessage(), rawDescription(), actual);
057 }
058
059 /**
060 * Verifies that the actual value satisfies the given condition.
061 * @param condition the given condition.
062 * @return this assertion object.
063 * @throws NullPointerException if the given condition is {@code null}.
064 * @throws AssertionError if the actual value does not satisfy the given condition.
065 * @see #is(Condition)
066 */
067 public final S satisfies(Condition<A> condition) {
068 if (matches(condition)) return myself;
069 failIfCustomMessageIsSet();
070 throw failure(errorMessageIfConditionNotSatisfied(condition));
071 }
072
073 private String errorMessageIfConditionNotSatisfied(Condition<A> condition) {
074 return condition.addDescriptionTo(format("actual value:<%s> should satisfy condition", actual));
075 }
076
077 /**
078 * Verifies that the actual value does not satisfy the given condition.
079 * @param condition the given condition.
080 * @return this assertion object.
081 * @throws NullPointerException if the given condition is {@code null}.
082 * @throws AssertionError if the actual value satisfies the given condition.
083 * @see #isNot(Condition)
084 */
085 public final S doesNotSatisfy(Condition<A> condition) {
086 if (!matches(condition)) return myself;
087 failIfCustomMessageIsSet();
088 throw failure(errorMessageIfConditionSatisfied(condition));
089 }
090
091 private String errorMessageIfConditionSatisfied(Condition<A> condition) {
092 return condition.addDescriptionTo(format("actual value:<%s> should not satisfy condition", actual));
093 }
094
095 /**
096 * Alias for <code>{@link #satisfies(Condition)}</code>.
097 * @param condition the given condition.
098 * @return this assertion object.
099 * @throws NullPointerException if the given condition is {@code null}.
100 * @throws AssertionError if the actual value does not satisfy the given condition.
101 * @since 1.2
102 */
103 public final S is(Condition<A> condition) {
104 if (matches(condition)) return myself;
105 failIfCustomMessageIsSet();
106 throw failure(errorMessageIfIsNot(condition));
107 }
108
109 private String errorMessageIfIsNot(Condition<A> condition) {
110 return condition.addDescriptionTo(format("actual value:<%s> should be", actual));
111 }
112
113 /**
114 * Alias for <code>{@link #doesNotSatisfy(Condition)}</code>.
115 * @param condition the given condition.
116 * @return this assertion object.
117 * @throws NullPointerException if the given condition is {@code null}.
118 * @throws AssertionError if the actual value satisfies the given condition.
119 * @since 1.2
120 */
121 public final S isNot(Condition<A> condition) {
122 if (!matches(condition)) return myself;
123 failIfCustomMessageIsSet();
124 throw failure(errorMessageIfIs(condition));
125 }
126
127 private boolean matches(Condition<A> condition) {
128 validateIsNotNull(condition);
129 return condition.matches(actual);
130 }
131
132 private void validateIsNotNull(Condition<A> condition) {
133 if (condition == null) throw new NullPointerException("Condition to check should not be null");
134 }
135
136 private String errorMessageIfIs(Condition<A> condition) {
137 return condition.addDescriptionTo(format("actual value:<%s> should not be", actual));
138 }
139
140 /**
141 * Sets the description of the actual value, to be used in as message of any <code>{@link AssertionError}</code>
142 * thrown when an assertion fails. This method should be called before any assertion method, otherwise any assertion
143 * failure will not show the provided description.
144 * <p>
145 * For example:
146 * <pre>
147 * assertThat(val).<strong>as</strong>("name").isEqualTo("Frodo");
148 * </pre>
149 * </p>
150 * @param description the description of the actual value.
151 * @return this assertion object.
152 */
153 public S as(String description) {
154 description(description);
155 return myself;
156 }
157
158 /**
159 * Alias for <code>{@link #as(String)}</code>, since "as" is a keyword in
160 * <a href="http://groovy.codehaus.org/" target="_blank">Groovy</a>. This method should be called before any assertion
161 * method, otherwise any assertion failure will not show the provided description.
162 * <p>
163 * For example:
164 * <pre>
165 * assertThat(val).<strong>describedAs</strong>("name").isEqualTo("Frodo");
166 * </pre>
167 * </p>
168 * @param description the description of the actual value.
169 * @return this assertion object.
170 */
171 public S describedAs(String description) {
172 return as(description);
173 }
174
175 /**
176 * Sets the description of the actual value, to be used in as message of any <code>{@link AssertionError}</code>
177 * thrown when an assertion fails. This method should be called before any assertion method, otherwise any assertion
178 * failure will not show the provided description.
179 * <p>
180 * For example:
181 * <pre>
182 * assertThat(val).<strong>as</strong>(new BasicDescription("name")).isEqualTo("Frodo");
183 * </pre>
184 * </p>
185 * @param description the description of the actual value.
186 * @return this assertion object.
187 */
188 public S as(Description description) {
189 description(description);
190 return myself;
191 }
192
193 /**
194 * Alias for <code>{@link #as(Description)}</code>, since "as" is a keyword in
195 * <a href="http://groovy.codehaus.org/" target="_blank">Groovy</a>. This method should be called before any assertion
196 * method, otherwise any assertion failure will not show the provided description.
197 * <p>
198 * For example:
199 * <pre>
200 * assertThat(val).<strong>describedAs</strong>(new BasicDescription("name")).isEqualTo("Frodo");
201 * </pre>
202 * </p>
203 * @param description the description of the actual value.
204 * @return this assertion object.
205 */
206 public S describedAs(Description description) {
207 return as(description);
208 }
209
210 /**
211 * Verifies that the actual value is equal to the given one.
212 * @param expected the given value to compare the actual value to.
213 * @return this assertion object.
214 * @throws AssertionError if the actual value is not equal to the given one.
215 */
216 public S isEqualTo(A expected) {
217 failIfNotEqual(customErrorMessage(), rawDescription(), actual, expected);
218 return myself;
219 }
220
221 /**
222 * Verifies that the actual value is not equal to the given one.
223 * @param other the given value to compare the actual value to.
224 * @return this assertion object.
225 * @throws AssertionError if the actual value is equal to the given one.
226 */
227 public S isNotEqualTo(A other) {
228 failIfEqual(customErrorMessage(), rawDescription(), actual, other);
229 return myself;
230 }
231
232 /**
233 * Verifies that the actual value is not {@code null}.
234 * @return this assertion object.
235 * @throws AssertionError if the actual value is {@code null}.
236 */
237 public final S isNotNull() {
238 failIfActualIsNull(customErrorMessage(), rawDescription(), actual);
239 return myself;
240 }
241
242 /**
243 * Verifies that the actual value is the same as the given one.
244 * @param expected the given value to compare the actual value to.
245 * @return this assertion object.
246 * @throws AssertionError if the actual value is not the same as the given one.
247 */
248 public final S isSameAs(A expected) {
249 failIfNotSame(customErrorMessage(), rawDescription(), actual, expected);
250 return myself;
251 }
252
253 /**
254 * Verifies that the actual value is not the same as the given one.
255 * @param other the given value to compare the actual value to.
256 * @return this assertion object.
257 * @throws AssertionError if the actual value is the same as the given one.
258 */
259 public final S isNotSameAs(A other) {
260 failIfSame(customErrorMessage(), rawDescription(), actual, other);
261 return myself;
262 }
263
264 /**
265 * Verifies that the actual value is in the given values.
266 * @param values the given values to search the actual value in.
267 * @return this assertion object.
268 * @throws AssertionError if the actual value is not in the given values.
269 * @throws NullPointerException if the given parameter is null.
270 */
271 public final S isIn(Object... values) {
272 return isIn(list(values));
273 }
274
275 /**
276 * Verifies that the actual value is in the given collection.
277 * @param values the given collection to search the actual value in. must not be null.
278 * @return this assertion object.
279 * @throws AssertionError if the actual value is not in the given collection.
280 * @throws NullPointerException if the given collection is null.
281 */
282 public final S isIn(Collection<?> values) {
283 if (values == null) throw new NullPointerException(formattedErrorMessage("expecting values parameter not to be null"));
284 if (isActualIn(values)) return myself;
285 failIfCustomMessageIsSet();
286 throw failure(unexpectedNotIn(customErrorMessage(), actual, values));
287 }
288
289 /**
290 * Verifies that the actual value is in the given values.
291 * @param values the given values to search the actual value in.
292 * @return this assertion object.
293 * @throws AssertionError if the actual value is not in the given values.
294 * @throws NullPointerException if the given parameter is null.
295 */
296 public final S isNotIn(Object... values) {
297 return isNotIn(list(values));
298 }
299
300 /**
301 * Verifies that the actual value is in the given collection.
302 * @param values the given collection to search the actual value in. must not be null.
303 * @return this assertion object.
304 * @throws AssertionError if the actual value is not in the given collection.
305 * @throws NullPointerException if the given collection is null.
306 */
307 public final S isNotIn(Collection<?> values) {
308 if (values == null) throw new NullPointerException(formattedErrorMessage("expecting values parameter not to be null"));
309 if (!isActualIn(values)) return myself;
310 failIfCustomMessageIsSet();
311 throw failure(unexpectedIn(customErrorMessage(), actual, values));
312 }
313
314 private boolean isActualIn(Collection<?> values) {
315 if (values.isEmpty()) return false;
316 for (Object value : values)
317 if (areEqual(actual, value)) return true;
318 return false;
319 }
320
321 /**
322 * Replaces the default message displayed in case of a failure with the given one.
323 * <p>
324 * For example, the following assertion:
325 * <pre>
326 * assertThat("Hello").isEqualTo("Bye");
327 * </pre>
328 * will fail with the default message "<em>expected:<'[Bye]'> but was:<'[Hello]'></em>."
329 * </p>
330 * <p>
331 * We can replace this message with our own:
332 * <pre>
333 * assertThat("Hello").overridingErrorMessage("'Hello' should be equal to 'Bye'").isEqualTo("Bye");
334 * </pre>
335 * in this case, the assertion will fail showing the message "<em>'Hello' should be equal to 'Bye'</em>".
336 * </p>
337 * @param message the given error message, which will replace the default one.
338 * @return this assertion.
339 * @since 1.2
340 */
341 public S overridingErrorMessage(String message) {
342 replaceDefaultErrorMessagesWith(message);
343 return myself;
344 }
345 }