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