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-2011 the original author or authors.
015     */
016    package org.fest.assertions;
017    
018    import static org.fest.assertions.ErrorMessages.unexpectedNullType;
019    import static org.fest.assertions.Formatting.format;
020    import static org.fest.util.Objects.namesOf;
021    
022    import java.util.Arrays;
023    
024    /**
025     * Assertions for <code>{@link Object}</code>s.
026     * <p>
027     * To create a new instance of this class use the method <code>{@link Assertions#assertThat(Object)}</code>.
028     * </p>
029     *
030     * @author Yvonne Wang
031     * @author Alex Ruiz
032     */
033    public class ObjectAssert extends GenericAssert<ObjectAssert, Object> {
034    
035      /**
036       * Creates a new </code>{@link ObjectAssert}</code>.
037       * @param actual the target to verify.
038       */
039      protected ObjectAssert(Object actual) {
040        super(ObjectAssert.class, actual);
041      }
042    
043      /**
044       * Verifies that the actual {@code Object} is an instance of the given type.
045       * @param type the type to check the actual {@code Object} against.
046       * @return this assertion object.
047       * @throws AssertionError if the actual {@code Object} is {@code null}.
048       * @throws AssertionError if the actual {@code Object} is not an instance of the given type.
049       * @throws NullPointerException if the given type is {@code null}.
050       */
051      public ObjectAssert isInstanceOf(Class<?> type) {
052        isNotNull();
053        validateNotNull(type);
054        Class<?> current = actual.getClass();
055        if (type.isAssignableFrom(current)) return this;
056        failIfCustomMessageIsSet();
057        throw failure(format("expected instance of:<%s> but was instance of:<%s>", type, current));
058      }
059    
060      /**
061       * Verifies that the actual {@code Object} is an instance of any of the given types.
062       * @param types the types to check the actual {@code Object} against.
063       * @return this assertion object.
064       * @throws AssertionError if the actual {@code Object} is {@code null}.
065       * @throws AssertionError if the actual {@code Object} is not an instance of any of the given types.
066       * @throws NullPointerException if the given array of types is {@code null}.
067       * @throws NullPointerException if the given array of types contains {@code null}s.
068       */
069      public ObjectAssert isInstanceOfAny(Class<?>...types) {
070        isNotNull();
071        if (types == null)
072          throw new NullPointerException(formattedErrorMessage("The given array of types should not be null"));
073        if (!foundInstanceOfAny(types))
074          fail(String.format(
075              "expected instance of any:<%s> but was instance of:<%s>", typeNames(types), actual.getClass().getName()));
076        return this;
077      }
078    
079      private boolean foundInstanceOfAny(Class<?>...types) {
080        Class<?> current = actual.getClass();
081        for (Class<?> type : types) {
082          validateNotNull(type);
083          if (type.isAssignableFrom(current)) return true;
084        }
085        return false;
086      }
087    
088      void validateNotNull(Class<?> type) {
089        if (type == null)
090          throw new NullPointerException(unexpectedNullType(rawDescription()));
091      }
092    
093      private String typeNames(Class<?>... types) {
094        return Arrays.toString(namesOf(types));
095      }
096    }