001    /*
002     * Created on Oct 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 java.util.Comparator;
018    import java.util.List;
019    
020    import org.fest.assertions.core.IndexedObjectEnumerableAssert;
021    import org.fest.assertions.data.Index;
022    import org.fest.assertions.internal.Lists;
023    import org.fest.util.ComparatorBasedComparisonStrategy;
024    import org.fest.util.VisibleForTesting;
025    
026    /**
027     * Assertion methods for <code>{@link List}</code>s.
028     * <p>
029     * To create an instance of this class, invoke <code>{@link Assertions#assertThat(List)}</code>.
030     * </p>
031     * 
032     * @author Yvonne Wang
033     * @author Alex Ruiz
034     * @author Joel Costigliola
035     * @author Mikhail Mazursky
036     */
037    // TODO inherits from IterableAssert and remove AbstractIterableAssert ? 
038    public class ListAssert<T> extends AbstractIterableAssert<ListAssert<T>, List<T>, T> implements IndexedObjectEnumerableAssert<T> {
039    
040      @VisibleForTesting
041      Lists lists = Lists.instance();
042    
043      protected ListAssert(List<T> actual) {
044        super(actual, ListAssert.class);
045      }
046    
047      /** {@inheritDoc} */
048      public ListAssert<T> contains(T value, Index index) {
049        lists.assertContains(info, actual, value, index);
050        return this;
051      }
052    
053      /** {@inheritDoc} */
054      public ListAssert<T> doesNotContain(T value, Index index) {
055        lists.assertDoesNotContain(info, actual, value, index);
056        return this;
057      }
058    
059      /**
060       * Verifies that the actual list is sorted into ascending order according to the natural ordering of its elements.
061       * <p>
062       * All list elements must implement the {@link Comparable} interface and must be mutually comparable (that is,
063       * e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list), examples :
064       * <ul>
065       * <li>a list composed of {"a1", "a2", "a3"} is ok because the element type (String) is Comparable</li>
066       * <li>a list composed of Rectangle {r1, r2, r3} is <b>NOT ok</b> because Rectangle is not Comparable</li>
067       * <li>a list composed of {True, "abc", False} is <b>NOT ok</b> because elements are not mutually comparable</li>
068       * </ul>
069       * Empty lists are considered sorted.</br> Unique element lists are considered sorted unless the element type is not
070       * Comparable.
071       * 
072       * @return {@code this} assertion object.
073       * 
074       * @throws AssertionError if the actual list is not sorted into ascending order according to the natural ordering of
075       *           its elements.
076       * @throws AssertionError if the actual list is <code>null</code>.
077       * @throws AssertionError if the actual list element type does not implement {@link Comparable}.
078       * @throws AssertionError if the actual list elements are not mutually {@link Comparable}.
079       */
080      public ListAssert<T> isSorted() {
081        lists.assertIsSorted(info, actual); 
082        return this;
083      }
084    
085      /**
086       * Verifies that the actual list is sorted according to the given comparator.</br> Empty lists are considered sorted
087       * whatever the comparator is.</br> One element lists are considered sorted if element is compatible with comparator.
088       * 
089       * @param comparator the {@link Comparator} used to compare list elements
090       * 
091       * @return {@code this} assertion object.
092       * 
093       * @throws AssertionError if the actual list is not sorted according to the given comparator.
094       * @throws AssertionError if the actual list is <code>null</code>.
095       * @throws NullPointerException if the given comparator is <code>null</code>.
096       * @throws AssertionError if the actual list elements are not mutually comparable according to given Comparator.
097       */
098      public ListAssert<T> isSortedAccordingTo(Comparator<? super T> comparator) {
099        lists.assertIsSortedAccordingToComparator(info, actual, comparator);
100        return this;
101      }
102    
103      @Override
104      public ListAssert<T> usingElementComparator(Comparator<? super T> customComparator) {
105        super.usingElementComparator(customComparator);
106        this.lists = new Lists(new ComparatorBasedComparisonStrategy(customComparator));
107        return myself;
108      }
109    
110      @Override
111      public ListAssert<T> usingDefaultElementComparator() {
112        super.usingDefaultElementComparator();
113        this.lists = Lists.instance();
114        return myself;
115      }
116    }