/*
* Copyright 2017 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.firebase.tasks;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.google.firebase.internal.NonNull;
import com.google.firebase.tasks.testing.TestOnCompleteListener;
import com.google.firebase.tasks.testing.TestOnFailureListener;
import com.google.firebase.tasks.testing.TestOnSuccessListener;
import java.rmi.RemoteException;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class TaskImplTest {
private static final Exception EXCEPTION = new RemoteException();
private static final Void NULL_RESULT = null;
private static final String NON_NULL_RESULT = "Success";
@Rule public ExpectedException expectedException = ExpectedException.none();
@Test
public void testIsComplete_notComplete() {
TaskImpl<Void> task = new TaskImpl<>();
assertFalse(task.isComplete());
}
@Test
public void testIsComplete_failed() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
assertTrue(task.isComplete());
}
@Test
public void testIsComplete_nullResult() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
assertTrue(task.isComplete());
}
@Test
public void testIsComplete_nonNullResult() {
TaskImpl<String> task = new TaskImpl<>();
task.setResult(NON_NULL_RESULT);
assertTrue(task.isComplete());
}
@Test
public void testIsSuccessful_notComplete() {
TaskImpl<Void> task = new TaskImpl<>();
assertFalse(task.isSuccessful());
}
@Test
public void testIsSuccessful_failed() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
assertFalse(task.isSuccessful());
}
@Test
public void testIsSuccessful_nullResult() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
assertTrue(task.isSuccessful());
}
@Test
public void testIsSuccessful_nonNullResult() {
TaskImpl<String> task = new TaskImpl<>();
task.setResult(NON_NULL_RESULT);
assertTrue(task.isSuccessful());
}
@Test(expected = IllegalStateException.class)
public void testGetResult_notComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.getResult();
}
@Test
public void testGetResult_nullResult() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
assertNull(task.getResult());
}
@Test
public void testGetResult_nonNullResult() {
TaskImpl<String> task = new TaskImpl<>();
task.setResult(NON_NULL_RESULT);
assertEquals(NON_NULL_RESULT, task.getResult());
}
@Test
public void testTrySetResult_nullResult() {
TaskImpl<Void> task = new TaskImpl<>();
assertTrue(task.trySetResult(NULL_RESULT));
assertNull(task.getResult());
}
@Test
public void testTrySetResult_nonNullResult() {
TaskImpl<String> task = new TaskImpl<>();
assertTrue(task.trySetResult(NON_NULL_RESULT));
assertEquals(NON_NULL_RESULT, task.getResult());
}
@Test
public void testGetResult_failure() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
expectedException.expect(RuntimeExecutionException.class);
expectedException.expectCause(Matchers.is(EXCEPTION));
task.getResult();
}
@Test
public void testGetResult_exceptionIsSpecifiedType() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
expectedException.expect(Matchers.is(EXCEPTION));
task.getResult(RemoteException.class);
}
@Test
public void testGetResult_exceptionIsNotSpecifiedType() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
Exception exception = new RuntimeException();
task.setException(exception);
expectedException.expect(RuntimeExecutionException.class);
expectedException.expectCause(Matchers.is(exception));
task.getResult(RemoteException.class);
}
@Test
public void testGetException_notComplete() {
TaskImpl<Void> task = new TaskImpl<>();
assertNull(task.getException());
}
@Test
public void testGetException_failure() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
assertEquals(EXCEPTION, task.getException());
}
@Test
public void testTrySetException() {
TaskImpl<Void> task = new TaskImpl<>();
assertTrue(task.trySetException(EXCEPTION));
assertEquals(EXCEPTION, task.getException());
}
@Test
public void testGetException_nullResult() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
assertNull(task.getException());
}
@Test
public void testGetException_nonNullResult() {
TaskImpl<String> task = new TaskImpl<>();
task.setResult(NON_NULL_RESULT);
assertNull(task.getException());
}
@Test
public void testOnSuccess_nullResult() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
TestOnSuccessListener<Void> listener = new TestOnSuccessListener<>();
task.addOnSuccessListener(listener);
task.setResult(NULL_RESULT);
assertTrue(listener.await());
assertNull(listener.getResult());
}
@Test
public void testOnSuccess_nonNullResult() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
TestOnSuccessListener<String> listener = new TestOnSuccessListener<>();
task.addOnSuccessListener(listener);
task.setResult(NON_NULL_RESULT);
assertTrue(listener.await());
assertEquals(NON_NULL_RESULT, listener.getResult());
}
@Test
public void testOnSuccess_alreadyComplete() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
TestOnSuccessListener<String> listener = new TestOnSuccessListener<>();
task.setResult(NON_NULL_RESULT);
task.addOnSuccessListener(listener);
assertTrue(listener.await());
assertEquals(NON_NULL_RESULT, listener.getResult());
}
@Test
public void testOnSuccess_acceptsBaseResult() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
TestOnSuccessListener<Object> listener = new TestOnSuccessListener<>();
task.setResult(NON_NULL_RESULT);
task.addOnSuccessListener(listener);
assertTrue(listener.await());
assertEquals(NON_NULL_RESULT, listener.getResult());
}
@Test
public void testOnFailure() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
TestOnFailureListener listener = new TestOnFailureListener();
task.addOnFailureListener(listener);
task.setException(EXCEPTION);
assertTrue(listener.await());
assertEquals(EXCEPTION, listener.getException());
}
@Test
public void testOnFailure_alreadyComplete() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
TestOnFailureListener listener = new TestOnFailureListener();
task.setException(EXCEPTION);
task.addOnFailureListener(listener);
assertTrue(listener.await());
assertEquals(EXCEPTION, listener.getException());
}
@Test
public void testOnComplete_nullResult() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
TestOnCompleteListener<Void> listener = new TestOnCompleteListener<>();
task.addOnCompleteListener(listener);
task.setResult(NULL_RESULT);
assertTrue(listener.await());
assertEquals(task, listener.getTask());
}
@Test
public void testOnComplete_nonNullResult() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
TestOnCompleteListener<String> listener = new TestOnCompleteListener<>();
task.addOnCompleteListener(listener);
task.setResult(NON_NULL_RESULT);
assertTrue(listener.await());
assertEquals(task, listener.getTask());
}
@Test
public void testOnComplete_failure() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
TestOnCompleteListener<String> listener = new TestOnCompleteListener<>();
task.addOnCompleteListener(listener);
task.setException(EXCEPTION);
assertTrue(listener.await());
assertEquals(task, listener.getTask());
}
@Test
public void testOnComplete_alreadySucceeded() throws Exception {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
TestOnCompleteListener<Void> listener = new TestOnCompleteListener<>();
task.addOnCompleteListener(listener);
assertTrue(listener.await());
assertEquals(task, listener.getTask());
}
@Test
public void testOnComplete_alreadyFailed() throws Exception {
TaskImpl<String> task = new TaskImpl<>();
task.setException(EXCEPTION);
TestOnCompleteListener<String> listener = new TestOnCompleteListener<>();
task.addOnCompleteListener(listener);
assertTrue(listener.await());
assertEquals(task, listener.getTask());
}
@Test
public void testContinueWith() {
TaskImpl<Void> task = new TaskImpl<>();
Task<String> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<Void, String>() {
@Override
public String then(@NonNull Task<Void> task) throws Exception {
assertNull(task.getResult());
return NON_NULL_RESULT;
}
});
task.setResult(null);
assertEquals(NON_NULL_RESULT, task2.getResult());
}
@Test
public void testContinueWith_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(null);
Task<Object> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<Void, Object>() {
@Override
public Object then(@NonNull Task<Void> task) throws Exception {
assertNull(task.getResult());
return NON_NULL_RESULT;
}
});
assertEquals(NON_NULL_RESULT, task2.getResult());
}
@Test
public void testContinueWith_propagatesException() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<Void, Void>() {
@Override
public Void then(@NonNull Task<Void> task) throws Exception {
task.getResult();
throw new AssertionError("Expected getResult to throw");
}
});
task.setException(EXCEPTION);
assertEquals(EXCEPTION, task2.getException());
}
@Test
public void testContinueWith_continuationThrows() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<Void, Void>() {
@Override
public Void then(@NonNull Task<Void> task) throws Exception {
throw EXCEPTION;
}
});
task.setResult(null);
assertEquals(EXCEPTION, task2.getException());
}
@Test
public void testContinueWith_continuationThrowsWrapperWithoutCause() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<Void, Void>() {
@Override
public Void then(@NonNull Task<Void> task) throws Exception {
throw new RuntimeExecutionException(null);
}
});
task.setResult(null);
assertThat(task2.getException(), instanceOf(RuntimeExecutionException.class));
}
@Test
public void testContinueWith_continuationReturnsNull() {
TaskImpl<String> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWith(
TaskExecutors.DIRECT,
new Continuation<String, Void>() {
@Override
public Void then(@NonNull Task<String> task) throws Exception {
assertEquals(NON_NULL_RESULT, task.getResult());
return null;
}
});
task.setResult(NON_NULL_RESULT);
assertNull(task2.getResult());
}
@Test
public void testContinueWithTask() {
TaskImpl<Void> task = new TaskImpl<>();
Task<String> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<String>>() {
@Override
public Task<String> then(@NonNull Task<Void> task) throws Exception {
assertNull(task.getResult());
return Tasks.forResult(NON_NULL_RESULT);
}
});
task.setResult(null);
assertEquals(NON_NULL_RESULT, task2.getResult());
}
@Test
public void testContinueWithTask_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(null);
Task<String> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<String>>() {
@Override
public Task<String> then(@NonNull Task<Void> task) throws Exception {
assertNull(task.getResult());
return Tasks.forResult(NON_NULL_RESULT);
}
});
assertEquals(NON_NULL_RESULT, task2.getResult());
}
@Test
public void testContinueWithTask_propagatesException() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<Void> task) throws Exception {
task.getResult();
throw new AssertionError("Expected getResult to throw");
}
});
task.setException(EXCEPTION);
assertEquals(EXCEPTION, task2.getException());
}
@Test
public void testContinueWithTask_continuationThrows() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<Void> task) throws Exception {
throw EXCEPTION;
}
});
task.setResult(null);
assertEquals(EXCEPTION, task2.getException());
}
@Test
public void testContinueWithTask_continuationThrowsWrapperWithoutCause() {
TaskImpl<Void> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<Void> task) throws Exception {
throw new RuntimeExecutionException(null);
}
});
task.setResult(null);
assertThat(task2.getException(), instanceOf(RuntimeExecutionException.class));
}
@Test
public void testContinueWithTask_continuationReturnsIncompleteTask() {
TaskImpl<Void> task = new TaskImpl<>();
final TaskImpl<String> task2 = new TaskImpl<>();
Task<String> task3 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<Void, Task<String>>() {
@Override
public Task<String> then(@NonNull Task<Void> task) throws Exception {
return task2;
}
});
task.setResult(NULL_RESULT);
assertFalse(task3.isComplete());
task2.setResult(NON_NULL_RESULT);
assertEquals(NON_NULL_RESULT, task3.getResult());
}
@Test
public void testContinueWithTask_continuationReturnsOriginalTask() {
TaskImpl<String> task = new TaskImpl<>();
Task<String> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<String, Task<String>>() {
@Override
public Task<String> then(@NonNull Task<String> task) throws Exception {
return task;
}
});
task.setResult(NON_NULL_RESULT);
assertEquals(NON_NULL_RESULT, task2.getResult());
}
@Test
public void testContinueWithTask_continuationReturnsNull() {
TaskImpl<String> task = new TaskImpl<>();
Task<Void> task2 =
task.continueWithTask(
TaskExecutors.DIRECT,
new Continuation<String, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<String> task) throws Exception {
assertEquals(NON_NULL_RESULT, task.getResult());
return null;
}
});
task.setResult(NON_NULL_RESULT);
assertThat(task2.getException(), instanceOf(NullPointerException.class));
}
@Test(expected = IllegalStateException.class)
public void testSetResult_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
task.setResult(NULL_RESULT);
}
@Test
public void testTrySetResult_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setException(EXCEPTION);
// Expect no exception to be thrown.
assertFalse(task.trySetResult(NULL_RESULT));
assertEquals(EXCEPTION, task.getException());
}
@Test(expected = IllegalStateException.class)
public void testSetException_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
task.setException(EXCEPTION);
}
@Test
public void testTrySetException_alreadyComplete() {
TaskImpl<Void> task = new TaskImpl<>();
task.setResult(NULL_RESULT);
// Expect no exception to be thrown.
assertFalse(task.trySetException(EXCEPTION));
assertNull(task.getResult());
}
}