001/*
002 * #%L
003 * Netarchivesuite - common - test
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.testutils;
025
026import java.util.ArrayList;
027import java.util.Arrays;
028import java.util.Iterator;
029import java.util.List;
030
031import dk.netarkivet.common.utils.Named;
032import junit.framework.TestCase;
033
034/**
035 * Utilities for doing asserts on collections.
036 */
037@SuppressWarnings({"rawtypes"})
038public class CollectionAsserts {
039
040    /**
041     * Test that two iterators contain the same objects in the same order. The objects are tested using equals(). The
042     * iterators will be used by this.
043     *
044     * @param msg Failure message
045     * @param i1 First iterator
046     * @param i2 Second iterator
047     */
048    public static <T> void assertIteratorEquals(String msg, Iterator<T> i1, Iterator<T> i2) {
049        while (i1.hasNext() && i2.hasNext()) {
050            T o1 = i1.next();
051            T o2 = i2.next();
052            TestCase.assertEquals(msg, o1, o2);
053        }
054        if (i1.hasNext()) {
055            TestCase.fail(msg + ": More elements in first iterator");
056        }
057        if (i2.hasNext()) {
058            TestCase.fail(msg + ": More elements in second iterator");
059        }
060    }
061
062    /**
063     * Assert iterators of Named or String-objects have equal names in any order.
064     *
065     * @param message Failure message
066     * @param i1 First iterator
067     * @param i2 Second iterator
068     */
069    public static void assertIteratorNamedEquals(String message, Iterator i1, Iterator i2) {
070        String[] a1 = getSortedArray(i1, message);
071        String[] a2 = getSortedArray(i2, message);
072        TestCase.assertTrue(message + "\n List 1: " + Arrays.asList(a1) + "\n List 2: " + Arrays.asList(a1),
073                Arrays.equals(a1, a2));
074    }
075
076    private static String[] getSortedArray(Iterator i1, String message) {
077        List<String> l1 = new ArrayList<String>();
078        while (i1.hasNext()) {
079            Object o = i1.next();
080            if (o instanceof Named) {
081                l1.add(((Named) o).getName());
082            } else if (o instanceof String) {
083                l1.add((String) o);
084            } else {
085                TestCase.fail(message + "(iterator of wrong kind of object '" + o + "' - " + o.getClass() + ")");
086            }
087        }
088        String[] a1 = l1.toArray(new String[] {});
089        Arrays.sort(a1);
090        return a1;
091    }
092
093    /**
094     * Assert that a list contains the given elements in order
095     *
096     * @param msg A message in case of failure
097     * @param actual A list of objects
098     * @param expected The values that the list should contain.
099     */
100    public static void assertListEquals(String msg, List<? extends Object> actual, Object... expected) {
101        if (actual == null) {
102            TestCase.fail(msg + ": Null list not expected");
103        }
104        if (expected.length != actual.size()) {
105            TestCase.fail(msg + ": Length mismatch: Expected " + expected.length + ", but got " + actual.size()
106                    + "\nExpected list: " + Arrays.asList(expected) + "\nActual list: " + actual);
107        }
108        for (int i = 0; i < expected.length; i++) {
109            final Object expectedValue = expected[i];
110            final Object actualValue = actual.get(i);
111            if (expectedValue != null) {
112                if (actualValue == null) {
113                    TestCase.fail(msg + ": Element " + i + " should be '" + expectedValue + "', but was null");
114                } else if (!expectedValue.equals(actualValue)) {
115                    TestCase.fail(msg + ": Element " + i + " should be '" + expectedValue + "', but was '"
116                            + actualValue + "'");
117                }
118            } else {
119                if (actualValue != null) {
120                    TestCase.fail(msg + ": Element " + i + " should be null, but was '" + actualValue);
121                }
122            }
123        }
124    }
125}