Java tutorial
/* * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.testing.util; import static java.util.Arrays.asList; import com.google.common.base.Objects; import com.google.common.collect.HashMultiset; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import java.util.Comparator; import junit.framework.Assert; import java.util.Iterator; import java.util.List; public final class MoreAsserts { private MoreAsserts() { } /** * Asserts that {@code actual} contains precisely the elements * {@code expected}, in any order. Both collections may contain * duplicates, and this method will only pass if the quantities are * exactly the same. */ public static void assertContentsAnyOrder(String message, Iterable<?> actual, Object... expected) { assertEqualsImpl(message, HashMultiset.create(asList(expected)), HashMultiset.create(actual)); } /** * Variant of {@link #assertContentsAnyOrder(String,Iterable,Object...)} * using a generic message. */ public static void assertContentsAnyOrder(Iterable<?> actual, Object... expected) { assertContentsAnyOrder((String) null, actual, expected); } /** * Asserts that {@code actual} contains precisely the elements * {@code expected}, in any order. Both collections may contain * duplicates, and this method will only pass if the quantities are * exactly the same. This method uses the user-provided Comparator * object for doing the object comparison, instead of relying on the * contents' implementation of {@link Object#equals(Object)}. It also takes * in the expected set of objects as an Iterable. * <p> * Note the different order of expected and actual from the other * {@link #assertContentsAnyOrder(String,Iterable,Object...)} */ public static <T> void assertContentsAnyOrder(String message, Iterable<? extends T> expected, Iterable<? extends T> actual, Comparator<? super T> comparator) { // We should not iterate over an Iterable more than once. There's // no guarentees that Iterable.iterator() returns an iterator over the // entire collection every time. // // Why don't we use TreeMultiset? Unfortunately, TreeMultiset.toString() // produces really odd output for duplicates. In addition, our contract // states that we use the comparator to compare equality, not to order // items. ImmutableList<T> actualList = ImmutableList.copyOf(actual); ImmutableList<T> expectedList = ImmutableList.copyOf(expected); // First compare sizes to save ourselves on N X M operation. // This also handles the case where "expected" is a subset of "actual". if (actualList.size() != expectedList.size()) { failNotEqual(message, expectedList, actualList); } // Now for each expected value, iterate through actuals and delete entry // if found. We need to make another copy of the "actual" items because // we will be removing items from this list, and we need to keep the original // for the failure message. List<T> unfoundItems = Lists.newLinkedList(actualList); for (T ex : expectedList) { boolean found = false; Iterator<T> iter = unfoundItems.iterator(); while (iter.hasNext()) { T ac = iter.next(); if (comparator.compare(ex, ac) == 0) { iter.remove(); found = true; break; } } if (!found) { failNotEqual(message, expectedList, actualList); } } } /** * Variant of {@link #assertContentsAnyOrder(String,Iterable,Object...)} * using a generic message. */ public static <T> void assertContentsAnyOrder(Iterable<? extends T> expected, Iterable<? extends T> actual, Comparator<? super T> comparator) { assertContentsAnyOrder((String) null, expected, actual, comparator); } private static void failNotEqual(String message, Object expected, Object actual) { if ((expected != null) && (actual != null) && expected.toString().equals(actual.toString())) { failWithMessage(message, "expected:<(" + expected.getClass().getName() + ") " + expected + "> but was:<(" + actual.getClass().getName() + ") " + actual + ">"); } else { failWithMessage(message, "expected:<" + expected + "> but was:<" + actual + ">"); } } /** * Replacement of {@link Assert#assertEquals} which provides the same error * message in GWT and java. */ private static void assertEqualsImpl(String message, Object expected, Object actual) { if (!Objects.equal(expected, actual)) { failWithMessage(message, "expected:<" + expected + "> but was:<" + actual + ">"); } } private static void failWithMessage(String userMessage, String ourMessage) { Assert.fail((userMessage == null) ? ourMessage : userMessage + ' ' + ourMessage); } }