/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.util; import com.google.common.base.Functions; import com.google.common.collect.Lists; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public final class JUnitUtils { public static void equalMaps(String message, Map<?, ?> expected, Map<?, ?> actual) { List<String> expectedStrings = Strings.entriesToString(expected); List<String> actualStrings = Strings.entriesToString(actual); Collections.sort(expectedStrings); Collections.sort(actualStrings); equalCollections(message, expectedStrings, actualStrings); } public static void equalCollections(String message, Collection<?> expected, Collection<?> actual) { if (expected == null) { assertEquals(message, expected, actual); } else if (!expected.equals(actual)) { assertEquals(message, Strings.join(expected), Strings.join(actual)); assertEquals(message, expected, actual); } } public static void equalsIncludingHash(String message, Object expected, Object actual) { assertEquals(message, expected, actual); assertEquals(message + " (hash code", expected.hashCode(), actual.hashCode()); } public static <T> void isUnmodifiable(String message, Collection<T> collection) { try { List<T> copy = new ArrayList<>(collection); collection.clear(); // good enough proxy for all modifications, for the JDK classes anyway collection.add(null); collection.addAll(copy); // restore the contents, in case someone wants to look in a debugger fail("collection is modifable: " + message); } catch (UnsupportedOperationException e) { // swallow } } public static <K, V> void isUnmodifiable(String message, Map<K, V> map) { try { Map<K, V> copy = new HashMap<>(map); map.clear(); // good enough proxy for all modifications, for the JDK classes anyway map.putAll(copy); // restore the map's contents, in case someone wants to look in a debugger fail("map is modifable: " + message); } catch (UnsupportedOperationException e) { // swallow } } public static <K, V> BuildingMap<K, V> map(K key, V value) { BuildingMap<K, V> map = new BuildingMap<>(); map.put(key, value); return map; } public static File getContainingFile(Class<?> cls) { String path = "src/test/resources/" + cls.getCanonicalName().replace('.', File.separatorChar); return new File(path).getParentFile(); } public static void expectMultipleCause(Runnable runnable, Class... expected) { List<Class> expectedList = Arrays.asList(expected); try { runnable.run(); fail("expected exception"); } catch(MultipleCauseException e) { for(Throwable c : e.getCauses()) { if(!expectedList.contains(c.getClass())) { fail("Unexpected cause: " + c); } assertEquals("Total causes", expected.length, e.getCauses().size()); } } } public static class BuildingMap<K,V> extends HashMap<K,V> { public BuildingMap<K, V> and(K key, V value) { put(key, value); return this; } private BuildingMap() {} } public static abstract class MessageTaker { private final List<String> messages = new ArrayList<>(); protected final void message(String label) { messages.add(label); } protected final void message(String label, Object... args) { List<String> line = Lists.transform(asList(args), Functions.toStringFunction()); messages.add(label +": " + line); } public final List<String> getMessages() { return messages; } } private JUnitUtils() {} }