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