001    /*
002     * $Id: CollectionTester.java,v 1.4 2013/12/19 20:45:39 oboehm Exp $
003     *
004     * Copyright (c) 2012 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 13.01.2012 by oliver (ob@oasd.de)
019     */
020    
021    package patterntesting.runtime.junit;
022    
023    import java.util.*;
024    
025    import patterntesting.runtime.util.Converter;
026    
027    /**
028     * If you want to assert that the content of two collections are equals use
029     * this tester here.
030     *
031     * @author oliver (ob@aosd.de)
032     * @since 1.2 (13.01.2012)
033     */
034    public final class CollectionTester {
035    
036        /** Utility class - no need to instantiate it. */
037        private CollectionTester() {}
038    
039        /**
040         * Checks if each object in collection c1 is equals to that of Collection c2.
041         * If not this method will tell you which element is different.
042         * If the collection have different size this method will tell you which
043         * element is missing.
044         * <p>
045         * The order of the elements is not relevant. I.e. two collections with different
046         * ordering of its elements are equals if they have both the same elements
047         * (independent from the internal ordering).
048         * </p>
049         * <p>
050         * Note: Use Lists ordering is important.
051         * </p>
052         *
053         * @param c1 the c1
054         * @param c2 the c2
055         */
056        public static void assertEquals(final Collection<?> c1, final Collection<?> c2) {
057            assertEquals(c1, c2, "collections differs");
058        }
059    
060        /**
061         * Assert equals. This method is not for public use but is used by
062         * MapTester. This is the reason why this method is 'protected'.
063         *
064         * @param c1 the c1
065         * @param c2 the c2
066         * @param msg the msg
067         */
068        protected static void assertEquals(final Collection<?> c1, final Collection<?> c2, final String msg) {
069            if (c1.size() < c2.size()) {
070                assertEquals(c2, c1);
071            } else {
072                assertEqualsSize(c1, c2);
073                for (Object elem1 : c1) {
074                    if (!c2.contains(elem1)) {
075                        throw new AssertionError(msg + ": ["
076                                + Converter.toShortString(elem1) + "] is not in "
077                                + Converter.toShortString(c2));
078                    }
079                }
080            }
081        }
082    
083        /**
084         * Checks if each object in list l1 is equals to that of list l2.
085         * If not this method will tell you which element is different.
086         * If the collection have different size this method will tell you which
087         * element is missing.
088         * <p>
089         * Because two lists are compared the order of the element is important.
090         * I.e. two lists with the same elements but different order are not
091         * equals.
092         * </p>
093         *
094         * @param l1 the list 1
095         * @param l2 the list 2
096         */
097        public static void assertEquals(final List<?> l1, final List<?> l2) {
098            if (l1.size() < l2.size()) {
099                assertEquals(l2, l1);
100            } else {
101                assertEqualsSize(l1, l2);
102                Iterator<?> iter1 = l1.iterator();
103                Iterator<?> iter2 = l2.iterator();
104                for (int i = 0; iter1.hasNext(); i++) {
105                    Object elem1 = iter1.next();
106                    Object elem2 = iter2.next();
107                    if (!elem1.equals(elem2)) {
108                        throw new AssertionError((i+1) + ". element differs ("
109                                + Converter.toShortString(elem1) + " != "
110                                + Converter.toShortString(elem2) + ")");
111                    }
112                }
113            }
114        }
115    
116        private static void assertEqualsSize(final Collection<?> c1, final Collection<?> c2)
117                throws AssertionError {
118            if (c1.size() > c2.size()) {
119                for (Object element : c1) {
120                    if (!c2.contains(element)) {
121                        throw new AssertionError("\"" + Converter.toShortString(element)
122                                + "\" is missing in " + Converter.toShortString(c2));
123                    }
124                }
125            }
126        }
127    
128    }
129