001    /*
002     * Created on Jun 28, 2010
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 @2010-2011 the original author or authors.
015     */
016    package org.fest.assertions;
017    
018    import org.fest.util.IntrospectionError;
019    
020    /**
021     * Template for assertions for arrays or collections.
022     * @param <S> used to simulate "self types." For more information please read &quot;<a
023     * href="http://passion.forco.de/content/emulating-self-types-using-java-generics-simplify-fluent-api-implementation"
024     * target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>.&quot;
025     * @param <A> the type the "actual" value.
026     *
027     * @author Yvonne Wang
028     *
029     * @since 1.3
030     */
031    public abstract class ObjectGroupAssert<S, A> extends ItemGroupAssert<S, A> {
032    
033      /**
034       * Creates a new </code>{@link ObjectGroupAssert}</code>.
035       * @param selfType the "self type."
036       * @param actual the target to verify.
037       */
038      protected ObjectGroupAssert(Class<S> selfType, A actual) {
039        super(selfType, actual);
040      }
041    
042      /**
043       * Verifies that the actual group of objects contains the given objects.
044       * @param objects the objects to look for.
045       * @return this assertion object.
046       * @throws AssertionError if the actual group of objects is {@code null}.
047       * @throws NullPointerException if the given array is {@code null}.
048       * @throws AssertionError if the actual group of objects does not contain the given objects.
049       */
050      public final S contains(Object... objects) {
051        assertContains(objects);
052        return myself;
053      }
054    
055      /**
056       * Verifies that the actual group of objects contains the given objects <strong>only</strong>, in any order.
057       * @param objects the objects to look for.
058       * @return this assertion object.
059       * @throws AssertionError if the actual group of objects is {@code null}.
060       * @throws NullPointerException if the given group of objects is {@code null}.
061       * @throws AssertionError if the actual group of objects does not contain the given objects, or if the actual group of
062       * objects contains elements other than the ones specified.
063       */
064      public final S containsOnly(Object... objects) {
065        assertContainsOnly(objects);
066        return myself;
067      }
068    
069      /**
070       * Verifies that the actual group of objects does not contain the given objects.
071       * @param objects the objects that the group of objects should exclude.
072       * @return this assertion object.
073       * @throws AssertionError if the actual group of objects is {@code null}.
074       * @throws NullPointerException if the given array is {@code null}.
075       * @throws AssertionError if the actual group of objects contains any of the given objects.
076       */
077      public final S excludes(Object... objects) {
078        assertExcludes(objects);
079        return myself;
080      }
081    
082      /**
083       * Verifies that the actual group of objects does not have duplicates.
084       * @return this assertion object.
085       * @throws AssertionError if the actual group of objects is {@code null}.
086       * @throws AssertionError if the actual group of objects has duplicates.
087       */
088      public final S doesNotHaveDuplicates() {
089        assertDoesNotHaveDuplicates();
090        return myself;
091      }
092    
093      /**
094       * Creates a new group of objects whose target collection contains the values of the given property name from the
095       * elements of the actual group of objects. Property access works with both simple properties like {@code Person.age}
096       * and nested properties {@code Person.father.age}.
097       * <p>
098       * For example, let's say we have a collection of {@code Person} objects and you want to verify their age:
099       * <pre>
100       * assertThat(persons).onProperty("age").containsOnly(25, 16, 44, 37); // simple property
101       * assertThat(persons).onProperty("father.age").containsOnly(55, 46, 74, 62); // nested property
102       * </p>
103       * @param propertyName the name of the property to extract values from the actual collection to build a new group of
104       * objects.
105       * @return a new group of objects containing the values of the given property name from the elements of the actual
106       * group of objects.
107       * @throws AssertionError if the actual group of objects is {@code null}.
108       * @throws IntrospectionError if an element in the given collection does not have a matching property.
109       * @since 1.3
110       */
111      protected abstract S onProperty(String propertyName);
112    }