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     */
029    public class ObjectAssert extends AbstractAssert<ObjectAssert, Object> {
030    
031      protected ObjectAssert(Object actual) {
032        super(actual, ObjectAssert.class);
033      }
034    
035      /**
036       * Verifies that the actual {@code Object} is an instance of the given type.
037       * @param type the type to check the actual {@code Object} against.
038       * @return this assertion object.
039       * @throws NullPointerException if the given type is {@code null}.
040       * @throws AssertionError if the actual {@code Object} is {@code null}.
041       * @throws AssertionError if the actual {@code Object} is not an instance of the given type.
042       */
043      public ObjectAssert isInstanceOf(Class<?> type) {
044        objects.assertIsInstanceOf(info, actual, type);
045        return this;
046      }
047    
048      /**
049       * Verifies that the actual {@code Object} is an instance of any of the given types.
050       * @param types the types to check the actual {@code Object} against.
051       * @return this assertion object.
052       * @throws AssertionError if the actual {@code Object} is {@code null}.
053       * @throws AssertionError if the actual {@code Object} is not an instance of any of the given types.
054       * @throws NullPointerException if the given array of types is {@code null}.
055       * @throws NullPointerException if the given array of types contains {@code null}s.
056       */
057      public ObjectAssert isInstanceOfAny(Class<?>... types) {
058        objects.assertIsInstanceOfAny(info, actual, types);
059        return this;
060      }
061    
062      /**
063       * Assert that the actual object is lenient equals to given one by only comparing actual and <b>not null</b> other
064       * fields.
065       * <p>
066       * It means that if an actual field is not null and the corresponding field in other is null, field will be ignored by
067       * lenient comparison, but the inverse will make assertion fail (null field in actual, not null in other).
068       * 
069       * <pre>
070       * Example: 
071       * 
072       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
073       * TolkienCharacter mysteriousHobbit = new TolkienCharacter(null, 33, HOBBIT); 
074       * 
075       * // Null fields in other/expected object are ignored, the mysteriousHobbit has null name thus name is ignored
076       * assertThat(frodo).isLenientEqualsToByIgnoringNullFields(mysteriousHobbit); //=> OK
077       * 
078       * // ... but the lenient equality is not reversible !
079       * assertThat(mysteriousHobbit).isLenientEqualsToByIgnoringNullFields(frodo); //=> FAIL
080       * 
081       * </pre>
082       * 
083       * @param other the object to compare {@code actual} to.
084       * @throws NullPointerException if the actual type is {@code null}.
085       * @throws NullPointerException if the other type is {@code null}.
086       * @throws AssertionError if the actual and the given object are not lenient equals.
087       * @throws AssertionError if the other object is not an instance of the actual type.
088       */
089      public ObjectAssert isLenientEqualsToByIgnoringNullFields(Object other) {
090        objects.assertIsLenientEqualsToByIgnoringNullFields(info, actual, other);
091        return this;
092      }
093    
094      /**
095       * Assert that the actual object is lenient equals to given one by only comparing actual and other on the given
096       * "accepted" fields only.
097       * 
098       * <pre>
099       * Example: 
100       * 
101       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
102       * TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT); 
103       * 
104       * // frodo and sam both are hobbits, so they are lenient equals on race
105       * assertThat(frodo).isLenientEqualsToByAcceptingFields(sam, "race"); //=> OK
106       * 
107       * // ... but not when accepting name and race
108       * assertThat(frodo).isLenientEqualsToByAcceptingFields(sam, "name", "race"); //=> FAIL
109       * 
110       * </pre>
111       * 
112       * @param other the object to compare {@code actual} to.
113       * @param fields accepted fields for lenient equality.
114       * @throws NullPointerException if the actual type is {@code null}.
115       * @throws NullPointerException if the other type is {@code null}.
116       * @throws AssertionError if the actual and the given object are not lenient equals.
117       * @throws AssertionError if the other object is not an instance of the actual type.
118       * @throws IntrospectionError if a field does not exist in actual.
119       */
120      public ObjectAssert isLenientEqualsToByAcceptingFields(Object other, String... fields) {
121        objects.assertIsLenientEqualsToByAcceptingFields(info, actual, other, fields);
122        return this;
123      }
124    
125      /**
126       * Assert that the actual object is lenient equals to given one by comparing actual and other fields except the given
127       * "ignored" fields.
128       * 
129       * <pre>
130       * Example: 
131       * 
132       * TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT); 
133       * TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT); 
134       * 
135       * // frodo and sam both are lenient equals ignoring name and age since only remaining property is race and frodo and sam both are HOBBIT
136       * assertThat(frodo).isLenientEqualsToByIgnoringFields(sam, "name", "age"); //=> OK
137       * 
138       * // ... but they are not lenient equals if only age is ignored because their names differ.
139       * assertThat(frodo).isLenientEqualsToByIgnoringFields(sam, "age"); //=> FAIL
140       * 
141       * </pre>
142       * 
143       * @param other the object to compare {@code actual} to.
144       * @param fields ignored fields for lenient equality.
145       * @throws NullPointerException if the actual type is {@code null}.
146       * @throws NullPointerException if the other type is {@code null}.
147       * @throws AssertionError if the actual and the given object are not lenient equals.
148       * @throws AssertionError if the other object is not an instance of the actual type.
149       */
150      public ObjectAssert isLenientEqualsToByIgnoringFields(Object other, String... fields) {
151        objects.assertIsLenientEqualsToByIgnoringFields(info, actual, other, fields);
152        return this;
153      }
154    
155    }