/*
* Copyright 2017 Gabor Varadi
*
* 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.zhuinden.simplestack;
import android.os.Parcelable;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Created by Zhuinden on 2017.01.20..
*/
public class BackstackTest {
StateChanger.Callback callback = null;
StateChange stateChange = null;
@Test
public void initialKeysShouldNotBeEmpty() {
try {
Backstack backstack = new Backstack();
Assert.fail();
} catch(IllegalArgumentException e) {
// good!
}
}
@Test
public void initialKeysShouldNotBeEmptyList() {
try {
Backstack backstack = new Backstack(new ArrayList<Parcelable>());
Assert.fail();
} catch(IllegalArgumentException e) {
// good!
}
}
@Test
public void initialKeysShouldNotBeNullList() {
try {
List<Parcelable> list = null;
Backstack backstack = new Backstack(list);
Assert.fail();
} catch(NullPointerException e) {
// good!
}
}
@Test
public void stateChangerShouldNotBeNull() {
try {
Backstack backstack = new Backstack(new TestKey("Hi"));
backstack.setStateChanger(null, Backstack.INITIALIZE);
Assert.fail();
} catch(NullPointerException e) {
// good!
}
}
@Test
public void newHistoryShouldNotBeNull() {
try {
Backstack backstack = new Backstack(new TestKey("Hi"));
backstack.setHistory(null, StateChange.FORWARD);
Assert.fail();
} catch(IllegalArgumentException e) {
// good!
}
}
@Test
public void newHistoryKeyShouldNotBeNull() {
try {
Backstack backstack = new Backstack(new TestKey("Hi"));
backstack.goTo(null);
Assert.fail();
} catch(IllegalArgumentException e) {
// good!
}
}
@Test
public void goBackShouldReturnTrueDuringActiveStateChange() {
TestKey hi = new TestKey("hi");
Backstack backstack = new Backstack(hi, new TestKey("bye"));
backstack.setStateChanger(new StateChanger() {
@Override
public void handleStateChange(StateChange stateChange, Callback completionCallback) {
callback = completionCallback;
}
}, Backstack.INITIALIZE);
callback.stateChangeComplete();
backstack.goTo(hi);
assertThat(backstack.goBack()).isTrue();
}
@Test
public void goBackShouldReturnFalseWithOneElement() {
TestKey hi = new TestKey("hi");
Backstack backstack = new Backstack(hi);
backstack.setStateChanger(new StateChanger() {
@Override
public void handleStateChange(StateChange stateChange, Callback completionCallback) {
callback = completionCallback;
}
}, Backstack.INITIALIZE);
callback.stateChangeComplete();
assertThat(backstack.goBack()).isFalse();
}
@Test
public void topPreviousStateReturnsNullDuringInitializeStateChange() {
TestKey hi = new TestKey("hi");
Backstack backstack = new Backstack(hi);
backstack.setStateChanger(new StateChanger() {
@Override
public void handleStateChange(StateChange stateChange, Callback completionCallback) {
assertThat(stateChange.topPreviousState()).isNull();
callback = completionCallback;
}
}, Backstack.INITIALIZE);
callback.stateChangeComplete();
}
@Test
public void topPreviousStateReturnsTop() {
final TestKey hi = new TestKey("hi");
final TestKey bye = new TestKey("bye");
Backstack backstack = new Backstack(hi, bye);
backstack.setStateChanger(new StateChanger() {
@Override
public void handleStateChange(StateChange stateChange, Callback completionCallback) {
if(!stateChange.getPreviousState().isEmpty()) {
assertThat(stateChange.topPreviousState()).isEqualTo(bye);
}
callback = completionCallback;
}
}, Backstack.INITIALIZE);
callback.stateChangeComplete();
backstack.goBack();
callback.stateChangeComplete();
}
@Test
public void pendingStateChangeCannotGoBackwards() {
PendingStateChange pendingStateChange = new PendingStateChange(null, StateChange.REPLACE, false);
pendingStateChange.setStatus(PendingStateChange.Status.COMPLETED);
try {
pendingStateChange.setStatus(PendingStateChange.Status.IN_PROGRESS);
Assert.fail();
} catch(IllegalStateException e) {
// Good!
}
}
@Test
public void pendingStateChangeStatusShouldNotBeNull() {
PendingStateChange pendingStateChange = new PendingStateChange(null, StateChange.REPLACE, false);
try {
pendingStateChange.setStatus(null);
Assert.fail();
} catch(NullPointerException e) {
// Good!
}
}
@Test
public void forceExecuteShouldExecuteAndSecondCallbackIsSwallowed() {
TestKey initial = new TestKey("hello");
Backstack backstack = new Backstack(initial);
StateChanger stateChanger = new StateChanger() {
@Override
public void handleStateChange(StateChange stateChange, Callback completionCallback) {
callback = completionCallback;
}
};
backstack.setStateChanger(stateChanger, Backstack.INITIALIZE);
backstack.executePendingStateChange();
assertThat(backstack.isStateChangePending()).isFalse();
callback.stateChangeComplete();
// no exception thrown
}
@Test
public void nullChangeListenerAddShouldThrow() {
TestKey initial = new TestKey("hello");
Backstack backstack = new Backstack(initial);
try {
backstack.addCompletionListener(null);
Assert.fail();
} catch(IllegalArgumentException e) {
// OK!
}
}
@Test
public void nullChangeListenerRemoveShouldThrow() {
TestKey initial = new TestKey("hello");
Backstack backstack = new Backstack(initial);
try {
backstack.removeCompletionListener(null);
Assert.fail();
} catch(IllegalArgumentException e) {
// OK!
}
}
@Test
public void completionListenerShouldBeCalled() {
TestKey initial = new TestKey("hello");
Backstack backstack = new Backstack(initial);
Backstack.CompletionListener completionListener = Mockito.mock(Backstack.CompletionListener.class);
StateChanger stateChanger = new StateChanger() {
@Override
public void handleStateChange(StateChange _stateChange, Callback completionCallback) {
stateChange = _stateChange;
callback = completionCallback;
}
};
backstack.addCompletionListener(completionListener);
backstack.setStateChanger(stateChanger, Backstack.INITIALIZE);
callback.stateChangeComplete();
assertThat(backstack.isStateChangePending()).isFalse();
Mockito.verify(completionListener, Mockito.only()).stateChangeCompleted(stateChange);
}
@Test
public void removedCompletionListenerShouldNotBeCalled() {
TestKey initial = new TestKey("hello");
Backstack backstack = new Backstack(initial);
Backstack.CompletionListener completionListener = Mockito.mock(Backstack.CompletionListener.class);
StateChanger stateChanger = new StateChanger() {
@Override
public void handleStateChange(StateChange _stateChange, Callback completionCallback) {
stateChange = _stateChange;
callback = completionCallback;
}
};
backstack.addCompletionListener(completionListener);
backstack.removeCompletionListener(completionListener);
backstack.setStateChanger(stateChanger, Backstack.INITIALIZE);
callback.stateChangeComplete();
assertThat(backstack.isStateChangePending()).isFalse();
Mockito.verify(completionListener, Mockito.never()).stateChangeCompleted(stateChange);
}
}