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 }