/******************************************************************************* * Copyright (c) 2011 Bruno Medeiros and other Contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package melnorme.utilbox.tests; import static melnorme.utilbox.core.Assert.AssertNamespace.assertFail; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import static melnorme.utilbox.core.CoreUtil.areEqual; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.BiConsumer; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.HashSet2; import melnorme.utilbox.collections.Indexable; import melnorme.utilbox.core.Assert; import melnorme.utilbox.core.Assert.AssertFailedException; import melnorme.utilbox.core.CoreUtil; import melnorme.utilbox.core.fntypes.RunnableX; import melnorme.utilbox.misc.ArrayUtil; import melnorme.utilbox.misc.FileUtil; import melnorme.utilbox.misc.Location; import melnorme.utilbox.misc.MiscUtil; import melnorme.utilbox.misc.PathUtil; import melnorme.utilbox.misc.StreamUtil; import melnorme.utilbox.misc.StringUtil; /** * A base class for common, miscellaneous test utils. */ public class CommonTestUtils { public static boolean TRUE() { return true; } public static void assertEquals(Object obj1, Object obj2) { Assert.equals(obj1, obj2); } public static void assertAreEqual(Object obj1, Object obj2) { assertTrue(CoreUtil.areEqual(obj1, obj2)); } @SuppressWarnings("unchecked") public static <T> T assertCast(Object object, Class<T> klass) { assertTrue(object == null || klass.isInstance(object)); return (T) object; } @SuppressWarnings("unchecked") public static <T> T assertInstance(Object object, Class<T> klass) { assertTrue(klass.isInstance(object)); return (T) object; } /** Assert that the given arrays are equal according to Arrays.equals(). * (equal content-wise, order relevant) */ public static void assertEqualArrays(Object[] arr1, Object[] arr2) { assertTrue(Arrays.equals(arr1, arr2)); } public static <T> void assertContains(T[] array, T obj) { assertTrue(ArrayUtil.contains(array, obj)); } public static void assertEquals(List<?> list1, List<?> list2) { assertAreEqualLists(list1, list2); } /** Helper for interactive debugging: * Does the same check as {@link List#equals(Object)}, but fails right on the spot where it's not equal. */ public static void assertAreEqualLists(List<?> list1, List<?> list2) { if(list1 == null && list2 == null) return; if(list1.size() != list2.size()) { assertFail(); } for (int ix = 0; ix < list1.size(); ix++) { Object obj1 = list1.get(ix); Object obj2 = list2.get(ix); assertAreEqual(obj1, obj2); } } public static void assertAreEqual(Indexable<?> obtained, Indexable<?> expected) { assertEqualIndexable(obtained, expected); } public static void assertEqualIndexable(Indexable<?> obtained, Indexable<?> expected) { if(obtained == null && expected == null) return; if(obtained.size() != expected.size()) { assertFail(); } for (int ix = 0; ix < obtained.size(); ix++) { Object obtainedObj = obtained.get(ix); Object expectedObj = expected.get(ix); assertAreEqual(obtainedObj, expectedObj); } } public static void checkEquals(Object obtained, Object expected) { if(!areEqual(expected, obtained)) { System.out.println("== checkEquals failed. Obtained:"); System.out.println(obtained); System.out.println("== Expected:"); System.out.println(expected); assertFail(); } } public static <T> void checkIndexable( Indexable<? extends T> obtained, Indexable<T> expected, BiConsumer<T, T> comparer ) { if(obtained == null && expected == null) return; if(obtained.size() != expected.size()) { assertFail(); } for (int ix = 0; ix < obtained.size(); ix++) { T obj1 = obtained.get(ix); T obj2 = expected.get(ix); comparer.accept(obj1, obj2); assertAreEqual(obj1, obj2); } } public static void assertEqualSet(Set<?> result, Set<?> expected) { boolean equals = result.equals(expected); if(equals) { return; } HashSet2<?> resultExtra = new HashSet2<Object>(result).removeAll2(expected); HashSet2<?> expectedMissing = new HashSet2<Object>(expected).removeAll2(result); assertTrue(equals, "Obtained result set not equal to expected set. \n" + "--- Extra elements in result set ("+resultExtra.size()+") : --- \n" + StringUtil.collToString(resultExtra, "\n") + "\n" + "--- Extra elements in expected set ("+expectedMissing.size()+") : --- \n" + StringUtil.collToString(expectedMissing, "\n") + "\n" + "== -- ==" ); } public static void verifyThrows(RunnableX<? extends Throwable> runnable) { verifyThrows(runnable, null); } public static void verifyThrows(RunnableX<?> runnable, Class<? extends Throwable> klass) { verifyThrows(runnable, klass, null); } public static void verifyThrows(RunnableX<?> runnable, Class<? extends Throwable> klass, String expectedExceptionString) { try { if(klass != null && AssertFailedException.class.isAssignableFrom(klass)) { Assert.assertionFailureExpected = true; } runnable.run(); // No exception thrown, check that this was what was expected assertTrue(klass == null && expectedExceptionString == null); } catch(Throwable e) { if(klass != null) { assertTrue(klass.isInstance(e)); } if(expectedExceptionString != null) { String exceptionStr = e.toString(); assertTrue(exceptionStr.contains(expectedExceptionString)); } } finally { Assert.assertionFailureExpected = false; } } public static void assertExceptionContains(Exception exception, String string) { if(string == null) { assertTrue(exception == null); } else { assertTrue(exception.toString().contains(string)); } } public static void assertExceptionMsgStart(Exception exception, String string) { if(string == null) { assertTrue(exception == null); } else { assertNotNull(exception); String message = exception.getMessage(); assertNotNull(message); assertTrue(message.startsWith(string)); } } public static <T> void assertStringContains(String string, CharSequence expectedContains) { assertTrue(string != null && string.contains(expectedContains)); } /* ---- */ public static <E> E unwrapSingle(Iterable<E> removeColl) { Iterator<E> iterator = removeColl.iterator(); assertTrue(iterator.hasNext()); E next = iterator.next(); assertTrue(iterator.hasNext() == false); return next; } public static <E, T extends Set<E>> T removeAll(T set, Collection<?> removeColl) { set.removeAll(removeColl); return set; } /* ----------------- util constructors ----------------- */ @SafeVarargs public static <T> T[] array(T... elems) { return elems; } @SafeVarargs public static String[] strings(String... elems) { return elems; } @SafeVarargs public static <T> ArrayList2<T> list(T... elems) { return ArrayList2.create(elems); } @SafeVarargs public static <T> HashSet2<T> hashSet(T... elems) { return new HashSet2<T>(Arrays.asList(elems)); } public static <T> Set<T> unmodifiable(Set<T> set) { return Collections.unmodifiableSet(set); } public static <T> List<T> unmodifiable(List<T> set) { return Collections.unmodifiableList(set); } public static <T> Collection<T> unmodifiable(Collection<T> set) { return Collections.unmodifiableCollection(set); } public static String safeToString(Object obj) { return obj == null ? null : obj.toString(); } /* ----------------- path utils ----------------- */ public static Path path(String pathString) { return PathUtil.createValidPath(pathString); } public static Location loc(String pathString) { Path createValidPath = PathUtil.createValidPath(pathString); return loc(createValidPath); } public static Location loc(Path absolutePath) { return Location.fromAbsolutePath(absolutePath); } public static Location loc(Location baseLoc, String pathString) { return baseLoc.resolve(PathUtil.createValidPath(pathString)); } public static Location workingDirLoc(String relativePath) { return TestsWorkingDir.getWorkingDir(relativePath); } /* ------------- Resources stuff ------------ */ public static final Charset DEFAULT_TESTDATA_ENCODING = StringUtil.UTF8; public static String readStringFromFile(Path path) { return readStringFromFile(Location.create_fromValid(path)); } public static String readStringFromFile(File file) { return readStringFromFile(Location.create_fromValid(file.toPath())); } public static String readStringFromFile(Location loc) { try { return FileUtil.readStringFromFile(loc.toFile(), DEFAULT_TESTDATA_ENCODING); } catch (IOException e) { throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e); } } public static void writeStringToFile(Path file, String string) { writeStringToFile(Location.create_fromValid(file), string); } public static void writeStringToFile(File file, String string) { writeStringToFile(Location.create_fromValid(file.toPath()), string); } public static void writeStringToFile(Location file, String string) { try { StreamUtil.writeStringToStream(string, new FileOutputStream(file.toFile()), DEFAULT_TESTDATA_ENCODING); } catch (IOException e) { throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e); } } public static void appendStringToFile(File file, String string) { try { StreamUtil.writeStringToStream(string, new FileOutputStream(file, true), DEFAULT_TESTDATA_ENCODING); } catch (IOException e) { throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e); } } public static String getClassResourceAsString(Class<?> klass, String resourceName) { return MiscUtil.getClassResource(klass, resourceName); } }