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 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 @2007-2011 the original author or authors.
014 */
015 package org.fest.assertions;
016
017 import static org.fest.assertions.ErrorMessages.*;
018 import static org.fest.assertions.Formatting.format;
019 import static org.fest.util.Collections.*;
020
021 import java.util.*;
022
023 import org.fest.util.IntrospectionError;
024
025 /**
026 * Assertions for {@code Object} arrays.
027 * <p>
028 * To create a new instance of this class invoke <code>{@link Assertions#assertThat(Object[])}</code>.
029 * </p>
030 *
031 * @author Yvonne Wang
032 * @author Alex Ruiz
033 */
034 public class ObjectArrayAssert extends ObjectGroupAssert<ObjectArrayAssert, 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(ObjectArrayAssert.class, actual);
042 }
043
044 /**
045 * Verifies that all the elements in the actual {@code Object} array belong to the specified type. Matching
046 * includes subclasses of the given type.
047 * <p>
048 * For example, consider the following code listing:
049 * <pre>
050 * Number[] numbers = { 2, 6 ,8 };
051 * assertThat(numbers).hasComponentType(Integer.class);
052 * </pre>
053 * The assertion <code>hasAllElementsOfType</code> will be successful.
054 * </p>
055 * @param type the expected type.
056 * @return this assertion object.
057 * @throws NullPointerException if the given type is {@code null}.
058 * @throws AssertionError if the component type of the actual {@code Object} array is not the same as the
059 * specified one.
060 */
061 public ObjectArrayAssert hasAllElementsOfType(Class<?> type) {
062 validateIsNotNull(type);
063 isNotNull();
064 for (Object o : actual) {
065 if (type.isInstance(o)) continue;
066 failIfCustomMessageIsSet();
067 fail(format("not all elements in array:<%s> belong to the type:<%s>", actual, type));
068 }
069 return this;
070 }
071
072 /**
073 * Verifies that at least one element in the actual {@code Object} array belong to the specified type. Matching
074 * includes subclasses of the given type.
075 * @param type the expected type.
076 * @return this assertion object.
077 * @throws AssertionError if the actual {@code Object} does not have any elements of the given type.
078 */
079 public ObjectArrayAssert hasAtLeastOneElementOfType(Class<?> type) {
080 validateIsNotNull(type);
081 isNotNull();
082 boolean found = false;
083 for (Object o : actual) {
084 if (!type.isInstance(o)) continue;
085 found = true;
086 break;
087 }
088 if (found) return this;
089 failIfCustomMessageIsSet();
090 throw failure(format("array:<%s> does not have any elements of type:<%s>", actual, type));
091 }
092
093 private void validateIsNotNull(Class<?> type) {
094 if (type == null) throw new NullPointerException(unexpectedNullType(rawDescription()));
095 }
096
097 /**
098 * Verifies that the actual {@code Object} array is equal to the given array. Array equality is checked by
099 * <code>{@link Arrays#deepEquals(Object[], Object[])}</code>.
100 * @param expected the given array to compare the actual array to.
101 * @return this assertion object.
102 * @throws AssertionError if the actual {@code Object} array is not equal to the given one.
103 */
104 @Override public ObjectArrayAssert isEqualTo(Object[] expected) {
105 if (Arrays.deepEquals(actual, expected)) return this;
106 failIfCustomMessageIsSet();
107 throw failure(unexpectedNotEqual(actual, expected));
108 }
109
110 /**
111 * Verifies that the actual {@code Object} array is not equal to the given array. Array equality is checked by
112 * <code>{@link Arrays#deepEquals(Object[], Object[])}</code>.
113 * @param array the given array to compare the actual array to.
114 * @return this assertion object.
115 * @throws AssertionError if the actual {@code Object} array is equal to the given one.
116 */
117 @Override public ObjectArrayAssert isNotEqualTo(Object[] array) {
118 if (!Arrays.deepEquals(actual, array)) return this;
119 failIfCustomMessageIsSet();
120 throw failure(unexpectedEqual(actual, array));
121 }
122
123 /**
124 * Creates a new instance of <code>{@link ObjectArrayAssert}</code> whose target array contains the values of the
125 * given property name from the elements of this {@code ObjectArrayAssert}'s array. Property access works with both
126 * simple properties like {@code Person.age} and nested properties {@code Person.father.age}.
127 * </p>
128 * <p>
129 * For example, let's say we have a array of {@code Person} objects and you want to verify their age:
130 * <pre>
131 * assertThat(persons).onProperty("age").containsOnly(25, 16, 44, 37); // simple property
132 * assertThat(persons).onProperty("father.age").containsOnly(55, 46, 74, 62); // nested property
133 * </p>
134 * @param propertyName the name of the property to extract values from the actual array to build a new
135 * {@code ObjectArrayAssert}.
136 * @return a new {@code ObjectArrayAssert} containing the values of the given property name from the elements of this
137 * {@code ObjectArrayAssert}'s array.
138 * @throws AssertionError if the actual array is {@code null}.
139 * @throws IntrospectionError if an element in the given array does not have a matching property.
140 * @since 1.3
141 */
142 @Override public ObjectArrayAssert onProperty(String propertyName) {
143 isNotNull();
144 if (actual.length == 0) return new ObjectArrayAssert(new Object[0]);
145 List<Object> values = PropertySupport.instance().propertyValues(propertyName, list(actual));
146 return new ObjectArrayAssert(values.toArray());
147 }
148
149 /** {@inheritDoc} */
150 @Override protected Set<Object> actualAsSet() {
151 return set(actual);
152 }
153
154 /** {@inheritDoc} */
155 @Override protected List<Object> actualAsList() {
156 return list(actual);
157 }
158
159 /** {@inheritDoc} */
160 @Override protected int actualGroupSize() {
161 return actual.length;
162 }
163 }