/** * Copyright 2009-2016 the original author or authors. * * 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 net.javacrumbs.futureconverter.common.test; import org.junit.Test; import java.io.IOException; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; /** * Abstract test conversion from F to type T. * * @param <F> from * @param <T> to */ public abstract class AbstractConverterTest<F extends Future<String>, T extends Future<String>> { public static final String VALUE = "test"; protected abstract T convert(F originalFuture); protected abstract F convertBack(T converted); protected abstract F createFinishedOriginal(); protected abstract F createExceptionalFuture(Exception exception); protected abstract F createRunningFuture(); protected abstract void addCallbackTo(T convertedFuture); protected abstract void verifyCallbackCalledWithCorrectValue() throws InterruptedException; protected abstract void waitForCalculationToFinish(T convertedFuture) throws InterruptedException; protected abstract void verifyCallbackCalledWithException(Exception exception) throws InterruptedException; protected abstract void verifyCallbackCalledWithException(Class<? extends Exception> exceptionClass) throws InterruptedException; protected abstract void finishOriginalFuture(); @Test public void testConvertCompleted() throws ExecutionException, InterruptedException { F originalFuture = createFinishedOriginal(); T converted = convert(originalFuture); assertEquals(VALUE, converted.get()); assertEquals(true, converted.isDone()); assertEquals(false, converted.isCancelled()); addCallbackTo(converted); verifyCallbackCalledWithCorrectValue(); } @Test public void testConvertRunning() throws ExecutionException, InterruptedException { F originalFuture = createRunningFuture(); T convertedFuture = convert(originalFuture); addCallbackTo(convertedFuture); assertEquals(false, convertedFuture.isDone()); assertEquals(false, convertedFuture.isCancelled()); finishOriginalFuture(); //wait for the result assertEquals(VALUE, convertedFuture.get()); assertEquals(true, convertedFuture.isDone()); assertEquals(false, convertedFuture.isCancelled()); waitForCalculationToFinish(convertedFuture); verifyCallbackCalledWithCorrectValue(); } @Test public void testCancelOriginal() throws ExecutionException, InterruptedException { F originalFuture = createRunningFuture(); originalFuture.cancel(true); T convertedFuture = convert(originalFuture); try { convertedFuture.get(); fail("Exception expected"); } catch (CancellationException e) { //ok } assertEquals(true, convertedFuture.isDone()); assertEquals(true, convertedFuture.isCancelled()); addCallbackTo(convertedFuture); verifyCallbackCalledWithException(CancellationException.class); } @Test public void testCancelNew() throws ExecutionException, InterruptedException { F originalFuture = createRunningFuture(); T convertedFuture = convert(originalFuture); convertedFuture.cancel(true); try { convertedFuture.get(); fail("Exception expected"); } catch (CancellationException e) { //ok } assertEquals(true, convertedFuture.isDone()); assertEquals(true, convertedFuture.isCancelled()); assertEquals(true, originalFuture.isDone()); assertEquals(true, originalFuture.isCancelled()); addCallbackTo(convertedFuture); verifyCallbackCalledWithException(CancellationException.class); } @Test public void testCancelBeforeConversion() throws ExecutionException, InterruptedException { F originalFuture = createRunningFuture(); originalFuture.cancel(true); T convertedFuture = convert(originalFuture); assertFalse(convertedFuture.cancel(true)); try { convertedFuture.get(); fail("Exception expected"); } catch (CancellationException e) { //ok } assertEquals(true, originalFuture.isDone()); assertEquals(true, originalFuture.isCancelled()); assertEquals(true, convertedFuture.isDone()); assertEquals(true, convertedFuture.isCancelled()); } @Test(expected = NullPointerException.class) public void shouldThrowNullPointerExceptionOnNull() { convert(null); } @Test public void shouldConvertBackToTheSameInstance() { F originalFuture = createFinishedOriginal(); T converted = convert(originalFuture); assertSame(originalFuture, convertBack(converted)); } @Test public void testCancelCompleted() throws ExecutionException, InterruptedException { F originalFuture = createFinishedOriginal(); T convertedFuture = convert(originalFuture); addCallbackTo(convertedFuture); waitForCalculationToFinish(convertedFuture); assertEquals(VALUE, convertedFuture.get()); assertEquals(true, convertedFuture.isDone()); assertEquals(false, convertedFuture.isCancelled()); verifyCallbackCalledWithCorrectValue(); assertFalse(convertedFuture.cancel(true)); } @Test public void testConvertWithException() throws ExecutionException, InterruptedException { Exception exception = new RuntimeException("test"); doTestException(exception); } @Test public void testConvertWithIOException() throws ExecutionException, InterruptedException { Exception exception = new IOException("test"); doTestException(exception); } protected void doTestException(final Exception exception) throws InterruptedException { F originalFuture = createExceptionalFuture(exception); T convertedFuture = convert(originalFuture); try { convertedFuture.get(); fail("Exception expected"); } catch (ExecutionException e) { assertEquals(exception, e.getCause()); } assertEquals(true, convertedFuture.isDone()); assertEquals(false, convertedFuture.isCancelled()); addCallbackTo(convertedFuture); verifyCallbackCalledWithException(exception); } }