001 /*
002 * Created on Dec 27, 2006
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 @2006-2009 the original author or authors.
015 */
016 package org.fest.assertions;
017
018 import static org.fest.assertions.Collections.found;
019 import static org.fest.assertions.Collections.notFound;
020 import static org.fest.assertions.Formatting.inBrackets;
021 import static org.fest.util.Collections.duplicatesFrom;
022 import static org.fest.util.Strings.concat;
023
024 import java.util.*;
025
026 import org.fest.util.Collections;
027
028 /**
029 * Understands assertions for collections. To create a new instance of this class use the
030 * method <code>{@link Assertions#assertThat(Collection)}</code>.
031 *
032 * @author Yvonne Wang
033 * @author Alex Ruiz
034 */
035 public class CollectionAssert extends GroupAssert<Collection<?>> {
036
037 /**
038 * Creates a new </code>{@link CollectionAssert}</code>.
039 * @param actual the target to verify.
040 */
041 protected CollectionAssert(Collection<?> actual) {
042 super(actual);
043 }
044
045 /**
046 * Verifies that the actual collection contains the given objects.
047 * @param objects the objects to look for.
048 * @return this assertion object.
049 * @throws AssertionError if the actual collection is <code>null</code>.
050 * @throws NullPointerException if the given array is <code>null</code>.
051 * @throws AssertionError if the actual collection does not contain the given objects.
052 */
053 public CollectionAssert contains(Object...objects) {
054 isNotNull();
055 validateIsNotNull(objects);
056 Collection<Object> notFound = notFoundInActual(objects);
057 if (notFound.isEmpty()) return this;
058 throw failureIfExpectedElementsNotFound(notFound);
059 }
060
061 private Collection<Object> notFoundInActual(Object... objects) {
062 return notFound(actual, objects);
063 }
064
065 /**
066 * Verifies that the actual collection contains the given objects <strong>only</strong>.
067 * @param objects the objects to look for.
068 * @return this assertion object.
069 * @throws AssertionError if the actual collection is <code>null</code>.
070 * @throws NullPointerException if the given array is <code>null</code>.
071 * @throws AssertionError if the actual collection does not contain the given objects, or if the actual collection
072 * contains elements other than the ones specified.
073 */
074 public CollectionAssert containsOnly(Object...objects) {
075 isNotNull();
076 validateIsNotNull(objects);
077 List<Object> copy = new ArrayList<Object>(actual);
078 List<Object> notFound = notFoundInCopy(copy, objects);
079 if (!notFound.isEmpty()) throw failureIfExpectedElementsNotFound(notFound);
080 if (copy.isEmpty()) return this;
081 throw failureIfUnexpectedElementsFound(copy);
082 }
083
084 private List<Object> notFoundInCopy(List<Object> copy, Object... objects) {
085 List<Object> notFound = new ArrayList<Object>();
086 for (Object o : objects) {
087 if (!copy.contains(o)) {
088 notFound.add(o);
089 continue;
090 }
091 copy.remove(o);
092 }
093 return notFound;
094 }
095
096 private AssertionError failureIfExpectedElementsNotFound(Collection<Object> notFound) {
097 failIfCustomMessageIsSet();
098 return failure(concat("collection:", format(actual), " does not contain element(s):", format(notFound)));
099 }
100
101 private AssertionError failureIfUnexpectedElementsFound(List<Object> unexpected) {
102 failIfCustomMessageIsSet();
103 return failure(concat("unexpected element(s):", format(unexpected), " in collection:", format(actual)));
104 }
105
106 /**
107 * Verifies that the actual collection does not contain the given objects.
108 * @param objects the objects that the collection should exclude.
109 * @return this assertion object.
110 * @throws AssertionError if the actual collection is <code>null</code>.
111 * @throws NullPointerException if the given array is <code>null</code>.
112 * @throws AssertionError if the actual collection contains any of the given objects.
113 */
114 public CollectionAssert excludes(Object...objects) {
115 isNotNull();
116 validateIsNotNull(objects);
117 Collection<Object> found = found(actual, objects);
118 if (found.isEmpty()) return this;
119 failIfCustomMessageIsSet();
120 throw failure(concat("collection:", format(actual), " does not exclude element(s):", format(found)));
121 }
122
123 private void validateIsNotNull(Object[] objects) {
124 if (objects == null)
125 throw new NullPointerException(formattedErrorMessage("the given array of objects should not be null"));
126 }
127
128 /**
129 * Verifies that the actual collection does not have duplicates.
130 * @return this assertion object.
131 * @throws AssertionError if the actual collection is <code>null</code>.
132 * @throws AssertionError if the actual collection has duplicates.
133 */
134 public CollectionAssert doesNotHaveDuplicates() {
135 isNotNull();
136 Collection<?> duplicates = duplicatesFrom(actual);
137 if (duplicates.isEmpty()) return this;
138 failIfCustomMessageIsSet();
139 throw failure(concat("collection:", format(actual), " contains duplicate(s):", format(duplicates)));
140 }
141
142 private String format(Collection<?> c) {
143 return inBrackets(c);
144 }
145
146 /** {@inheritDoc} */
147 public CollectionAssert as(String description) {
148 description(description);
149 return this;
150 }
151
152 /** {@inheritDoc} */
153 public CollectionAssert describedAs(String description) {
154 return as(description);
155 }
156
157 /** {@inheritDoc} */
158 public CollectionAssert as(Description description) {
159 description(description);
160 return this;
161 }
162
163 /** {@inheritDoc} */
164 public CollectionAssert describedAs(Description description) {
165 return as(description);
166 }
167
168 /**
169 * Verifies that the actual collection satisfies the given condition.
170 * @param condition the given condition.
171 * @return this assertion object.
172 * @throws NullPointerException if the given condition is <code>null</code>.
173 * @throws AssertionError if the actual collection does not satisfy the given condition.
174 * @see #is(Condition)
175 */
176 public CollectionAssert satisfies(Condition<Collection<?>> condition) {
177 assertSatisfies(condition);
178 return this;
179 }
180
181 /**
182 * Verifies that the actual collection does not satisfy the given condition.
183 * @param condition the given condition.
184 * @return this assertion object.
185 * @throws NullPointerException if the given condition is <code>null</code>.
186 * @throws AssertionError if the actual collection satisfies the given condition.
187 * @see #isNot(Condition)
188 */
189 public CollectionAssert doesNotSatisfy(Condition<Collection<?>> condition) {
190 assertDoesNotSatisfy(condition);
191 return this;
192 }
193
194 /**
195 * Alias for <code>{@link #satisfies(Condition)}</code>.
196 * @param condition the given condition.
197 * @return this assertion object.
198 * @throws NullPointerException if the given condition is <code>null</code>.
199 * @throws AssertionError if the actual collection does not satisfy the given condition.
200 * @since 1.2
201 */
202 public CollectionAssert is(Condition<Collection<?>> condition) {
203 assertIs(condition);
204 return this;
205 }
206
207 /**
208 * Alias for <code>{@link #doesNotSatisfy(Condition)}</code>.
209 * @param condition the given condition.
210 * @return this assertion object.
211 * @throws NullPointerException if the given condition is <code>null</code>.
212 * @throws AssertionError if the actual collection satisfies the given condition.
213 * @since 1.2
214 */
215 public CollectionAssert isNot(Condition<Collection<?>> condition) {
216 assertIsNot(condition);
217 return this;
218 }
219
220 /**
221 * Verifies that the actual collection is <code>null</code> or empty.
222 * @throws AssertionError if the actual collection is not <code>null</code> or not empty.
223 */
224 public void isNullOrEmpty() {
225 if (Collections.isEmpty(actual)) return;
226 failIfCustomMessageIsSet();
227 fail(concat("expecting a null or empty collection, but was:", format(actual)));
228 }
229
230 /**
231 * Verifies that the actual collection is not <code>null</code>.
232 * @return this assertion object.
233 * @throws AssertionError if the actual collection is <code>null</code>.
234 */
235 public CollectionAssert isNotNull() {
236 if (actual != null) return this;
237 failIfCustomMessageIsSet();
238 throw failure("expecting a non-null collection, but it was null");
239 }
240
241 /**
242 * Verifies that the actual collection is empty (not <code>null</code> with zero elements.)
243 * @throws AssertionError if the actual collection is <code>null</code>.
244 * @throws AssertionError if the actual collection is not empty.
245 */
246 public void isEmpty() {
247 isNotNull();
248 if (Collections.isEmpty(actual)) return;
249 failIfCustomMessageIsSet();
250 fail(concat("expecting empty collection, but was:", format(actual)));
251 }
252
253 /**
254 * Verifies that the actual collection contains at least on element.
255 * @return this assertion object.
256 * @throws AssertionError if the actual collection is <code>null</code>.
257 * @throws AssertionError if the actual collection is empty.
258 */
259 public CollectionAssert isNotEmpty() {
260 isNotNull();
261 if (!actual.isEmpty()) return this;
262 failIfCustomMessageIsSet();
263 throw failure("expecting a non-empty collection, but it was empty");
264 }
265
266 /**
267 * Verifies that the number of elements in the actual collection is equal to the given one.
268 * @param expected the expected number of elements in the actual collection.
269 * @return this assertion object.
270 * @throws AssertionError if the actual collection is <code>null</code>.
271 * @throws AssertionError if the number of elements of the actual collection is not equal to the given one.
272 */
273 public CollectionAssert hasSize(int expected) {
274 int actualSize = actualGroupSize();
275 if (actualSize == expected) return this;
276 failIfCustomMessageIsSet();
277 throw failure(concat(
278 "expected size:", inBrackets(expected)," but was:", inBrackets(actualSize), " for collection:", format(actual)));
279 }
280
281 /**
282 * Returns the number of elements in the actual collection.
283 * @return the number of elements in the actual collection.
284 */
285 protected int actualGroupSize() {
286 isNotNull();
287 return actual.size();
288 }
289
290 /**
291 * Verifies that the actual collection is equal to the given one.
292 * @param expected the given collection to compare the actual collection to.
293 * @return this assertion object.
294 * @throws AssertionError if the actual collection is not equal to the given one.
295 */
296 public CollectionAssert isEqualTo(Collection<?> expected) {
297 assertEqualTo(expected);
298 return this;
299 }
300
301 /**
302 * Verifies that the actual collection is not equal to the given one.
303 * @param other the given collection to compare the actual collection to.
304 * @return this assertion object.
305 * @throws AssertionError if the actual collection is equal to the given one.
306 */
307 public CollectionAssert isNotEqualTo(Collection<?> other) {
308 assertNotEqualTo(other);
309 return this;
310 }
311
312 /**
313 * Verifies that the actual collection is the same as the given one.
314 * @param expected the given collection to compare the actual collection to.
315 * @return this assertion object.
316 * @throws AssertionError if the actual collection is not the same as the given one.
317 */
318 public CollectionAssert isSameAs(Collection<?> expected) {
319 assertSameAs(expected);
320 return this;
321 }
322
323 /**
324 * Verifies that the actual collection is not the same as the given one.
325 * @param other the given collection to compare the actual collection to.
326 * @return this assertion object.
327 * @throws AssertionError if the actual collection is the same as the given one.
328 */
329 public CollectionAssert isNotSameAs(Collection<?> other) {
330 assertNotSameAs(other);
331 return this;
332 }
333
334 /** {@inheritDoc} */
335 public CollectionAssert overridingErrorMessage(String message) {
336 replaceDefaultErrorMessagesWith(message);
337 return this;
338 }
339 }