001    /*
002     * Created on Dec 26, 2010
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * 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 is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     * 
013     * Copyright @2010-2011 the original author or authors.
014     */
015    package org.fest.assertions.api;
016    
017    import org.fest.util.IntrospectionError;
018    
019    /**
020     * Assertion methods for {@code Object}s.
021     * <p>
022     * To create a new instance of this class, invoke <code>{@link Assertions#assertThat(Object)}</code>.
023     * </p>
024     * 
025     * @author Yvonne Wang
026     * @author Alex Ruiz
027     * @author Nicolas François
028     * @author Mikhail Mazursky
029     */
030    public class ObjectAssert<T> extends AbstractAssert<ObjectAssert<T>, T> {
031    
032      protected ObjectAssert(T actual) {
033        super(actual, ObjectAssert.class);
034      }
035    
036      /**
037       * Verifies that the actual {@code Object} is an instance of the given type.
038       * @param type the type to check the actual {@code Object} against.
039       * @return this assertion object.
040       * @throws NullPointerException if the given type is {@code null}.
041       * @throws AssertionError if the actual {@code Object} is {@code null}.
042       * @throws AssertionError if the actual {@code Object} is not an instance of the given type.
043       */
044      public ObjectAssert<T> isInstanceOf(Class<?> type) {
045        objects.assertIsInstanceOf(info, actual, type);
046        return this;
047      }
048    
049      /**
050       * Verifies that the actual {@code Object} is an instance of any of the given types.
051       * @param types the types to check the actual {@code Object} against.
052       * @return this assertion object.
053       * @throws AssertionError if the actual {@code Object} is {@code null}.
054       * @throws AssertionError if the actual {@code Object} is not an instance of any of the given types.
055       * @throws NullPointerException if the given array of types is {@code null}.
056       * @throws NullPointerException if the given array of types contains {@code null}s.
057       */
058      public ObjectAssert<T> isInstanceOfAny(Class<?>... types) {
059        objects.assertIsInstanceOfAny(info, actual, types);
060        return this;
061      }
062    
063      /**
064       * Assert that the actual object is lenient equals to given one by only comparing actual and <b>not null</b> other
065       * fields.
066       * <p>
067       * It means that if an actual field is not null and the corresponding field in other is null, field will be ignored by
068       * lenient comparison, but the inverse will make assertion fail (null field in actual, not null in other).
069       * 
070       * <pre>
071       * Example: 
072       * 
073       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
074       * TolkienCharacter mysteriousHobbit = new TolkienCharacter(null, 33, HOBBIT); 
075       * 
076       * // Null fields in other/expected object are ignored, the mysteriousHobbit has null name thus name is ignored
077       * assertThat(frodo).isLenientEqualsToByIgnoringNullFields(mysteriousHobbit); //=> OK
078       * 
079       * // ... but the lenient equality is not reversible !
080       * assertThat(mysteriousHobbit).isLenientEqualsToByIgnoringNullFields(frodo); //=> FAIL
081       * 
082       * </pre>
083       * 
084       * @param other the object to compare {@code actual} to.
085       * @throws NullPointerException if the actual type is {@code null}.
086       * @throws NullPointerException if the other type is {@code null}.
087       * @throws AssertionError if the actual and the given object are not lenient equals.
088       * @throws AssertionError if the other object is not an instance of the actual type.
089       */
090      public ObjectAssert<T> isLenientEqualsToByIgnoringNullFields(T other) {
091        objects.assertIsLenientEqualsToByIgnoringNullFields(info, actual, other);
092        return this;
093      }
094    
095      /**
096       * Assert that the actual object is lenient equals to given one by only comparing actual and other on the given
097       * "accepted" fields only.
098       * 
099       * <pre>
100       * Example: 
101       * 
102       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
103       * TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT); 
104       * 
105       * // frodo and sam both are hobbits, so they are lenient equals on race
106       * assertThat(frodo).isLenientEqualsToByAcceptingFields(sam, "race"); //=> OK
107       * 
108       * // ... but not when accepting name and race
109       * assertThat(frodo).isLenientEqualsToByAcceptingFields(sam, "name", "race"); //=> FAIL
110       * 
111       * </pre>
112       * 
113       * @param other the object to compare {@code actual} to.
114       * @param fields accepted fields for lenient equality.
115       * @throws NullPointerException if the actual type is {@code null}.
116       * @throws NullPointerException if the other type is {@code null}.
117       * @throws AssertionError if the actual and the given object are not lenient equals.
118       * @throws AssertionError if the other object is not an instance of the actual type.
119       * @throws IntrospectionError if a field does not exist in actual.
120       */
121      public ObjectAssert<T> isLenientEqualsToByAcceptingFields(T other, String... fields) {
122        objects.assertIsLenientEqualsToByAcceptingFields(info, actual, other, fields);
123        return this;
124      }
125    
126      /**
127       * Assert that the actual object is lenient equals to given one by comparing actual and other fields except the given
128       * "ignored" fields.
129       * 
130       * <pre>
131       * Example: 
132       * 
133       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
134       * TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT); 
135       * 
136       * // frodo and sam both are lenient equals ignoring name and age since only remaining property is race and frodo and sam both are HOBBIT
137       * assertThat(frodo).isLenientEqualsToByIgnoringFields(sam, "name", "age"); //=> OK
138       * 
139       * // ... but they are not lenient equals if only age is ignored because their names differ.
140       * assertThat(frodo).isLenientEqualsToByIgnoringFields(sam, "age"); //=> FAIL
141       * 
142       * </pre>
143       * 
144       * @param other the object to compare {@code actual} to.
145       * @param fields ignored fields for lenient equality.
146       * @throws NullPointerException if the actual type is {@code null}.
147       * @throws NullPointerException if the other type is {@code null}.
148       * @throws AssertionError if the actual and the given object are not lenient equals.
149       * @throws AssertionError if the other object is not an instance of the actual type.
150       */
151      public ObjectAssert<T> isLenientEqualsToByIgnoringFields(T other, String... fields) {
152        objects.assertIsLenientEqualsToByIgnoringFields(info, actual, other, fields);
153        return this;
154      }
155    
156    }