/*
* Copyright 2016 Kejun Xia
*
* 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.shipdream.lib.android.mvc.view;
import android.os.Bundle;
import android.view.View;
import com.shipdream.lib.android.mvc.Reason;
import com.shipdream.lib.android.mvc.view.help.LifeCycleMonitor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import org.mockito.exceptions.base.MockitoAssertionError;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.isNotNull;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class LifeCycleValidator {
private final LifeCycleMonitor lifeCycleMonitorMock;
public LifeCycleValidator(LifeCycleMonitor lifeCycleMonitorMock) {
this.lifeCycleMonitorMock = lifeCycleMonitorMock;
}
protected int onCreateCountNull;
protected int onCreateCountNotNull;
protected int onCreateViewCountNull;
protected int onCreateViewCountNotNull;
protected int onViewCreatedCountNull;
protected int onViewCreatedCountNotNull;
protected int onViewReadyNewInstance;
protected int onViewReadyFirstTime;
protected int onViewReadyRotation;
protected int onViewReadyRestore;
protected int onViewReadyPopOut;
protected int onPushToBackStackCount;
protected int onPopAwayCount;
protected int onPoppedOutToFrontCount;
protected int onReturnForegroundCount;
protected int onOrientationChangedCount;
protected int onDestroyViewCount;
protected int onDestroyCount;
private final static long wait_span = 5000;
public void expect(LifeCycle... lifeCycles){
long start = System.currentTimeMillis();
while(true) {
long elapse = System.currentTimeMillis() - start;
try {
doExpect(lifeCycles);
} catch (MockitoAssertionError mockitoAssertionError) {
if (elapse > wait_span) {
throw mockitoAssertionError;
} else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//Pass
break;
}
}
private void doExpect(LifeCycle... lifeCycles) {
if (lifeCycles != null) {
for (int i = 0; i < lifeCycles.length; i++) {
LifeCycle lifeCycle = lifeCycles[i];
switch (lifeCycle) {
case onCreateNull:
onCreateCountNull++;
break;
case onCreateNotNull:
onCreateCountNotNull++;
break;
case onCreateViewNull:
onCreateViewCountNull++;
break;
case onCreateViewNotNull:
onCreateViewCountNotNull++;
break;
case onViewCreatedNull:
onViewCreatedCountNull++;
break;
case onViewCreatedNotNull:
onViewCreatedCountNotNull++;
break;
case onViewReadyNewInstance:
onViewReadyNewInstance++;
break;
case onViewReadyFirstTime:
onViewReadyFirstTime++;
break;
case onViewReadyRotate:
onViewReadyRotation++;
break;
case onViewReadyRestore:
onViewReadyRestore++;
break;
case onViewReadyPopOut:
onViewReadyPopOut++;
break;
case onPushToBackStack:
onPushToBackStackCount++;
break;
case onPopAway:
onPopAwayCount++;
break;
case onPoppedOutToFront:
onPoppedOutToFrontCount++;
break;
case onReturnForeground:
onReturnForegroundCount++;
break;
case onOrientationChanged:
onOrientationChangedCount++;
break;
case onDestroyView:
onDestroyViewCount++;
break;
case onDestroy:
onDestroyCount++;
break;
}
}
}
verify(lifeCycleMonitorMock, times(onCreateCountNull)).onCreate(null);
verify(lifeCycleMonitorMock, times(onCreateCountNotNull)).onCreate(isNotNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onCreateViewCountNull)).onCreateView(any(View.class), isNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onCreateViewCountNotNull)).onCreateView(any(View.class), isNotNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onViewCreatedCountNull)).onViewCreated(any(View.class), isNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onViewCreatedCountNotNull)).onViewCreated(any(View.class), isNotNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onViewReadyNewInstance)).onViewReady(any(View.class),
any(Bundle.class), argThat(new NewInstanceMatcher()));
verify(lifeCycleMonitorMock, times(onViewReadyFirstTime)).onViewReady(any(View.class),
any(Bundle.class), argThat(new FirstTimeMatcher()));
verify(lifeCycleMonitorMock, times(onViewReadyRotation)).onViewReady(any(View.class),
any(Bundle.class), argThat(new RotateMatcher()));
verify(lifeCycleMonitorMock, times(onViewReadyRestore)).onViewReady(any(View.class),
any(Bundle.class), argThat(new RestoreMatcher()));
verify(lifeCycleMonitorMock, times(onViewReadyPopOut)).onViewReady(any(View.class),
any(Bundle.class), argThat(new PopOutMatcher()));
verify(lifeCycleMonitorMock, times(onViewCreatedCountNotNull)).onViewCreated(any(View.class), isNotNull(Bundle.class));
verify(lifeCycleMonitorMock, times(onPushToBackStackCount)).onPushToBackStack();
verify(lifeCycleMonitorMock, times(onPopAwayCount)).onPopAway();
verify(lifeCycleMonitorMock, times(onPoppedOutToFrontCount)).onPoppedOutToFront();
verify(lifeCycleMonitorMock, times(onReturnForegroundCount)).onReturnForeground();
verify(lifeCycleMonitorMock, times(onOrientationChangedCount)).onOrientationChanged(anyInt(), anyInt());
verify(lifeCycleMonitorMock, times(onDestroyViewCount)).onDestroyView();
verify(lifeCycleMonitorMock, times(onDestroyCount)).onDestroy();
reset();
}
private class NewInstanceMatcher extends ArgumentMatcher<Reason> {
@Override
public boolean matches(Object argument) {
if (argument instanceof Reason) {
if (((Reason) argument).isNewInstance()) {
return true;
}
}
return false;
}
}
private class FirstTimeMatcher extends ArgumentMatcher<Reason> {
@Override
public boolean matches(Object argument) {
if (argument instanceof Reason) {
if (((Reason) argument).isFirstTime()) {
return true;
}
}
return false;
}
}
private class RestoreMatcher extends ArgumentMatcher<Reason> {
@Override
public boolean matches(Object argument) {
if (argument instanceof Reason) {
if (((Reason) argument).isRestored()) {
return true;
}
}
return false;
}
}
private class RotateMatcher extends ArgumentMatcher<Reason> {
@Override
public boolean matches(Object argument) {
if (argument instanceof Reason) {
if (((Reason) argument).isRotated()) {
return true;
}
}
return false;
}
}
private class PopOutMatcher extends ArgumentMatcher<Reason> {
@Override
public boolean matches(Object argument) {
if (argument instanceof Reason) {
if (((Reason) argument).isPoppedOut()) {
return true;
}
}
return false;
}
}
public void reset() {
onCreateCountNull = 0;
onCreateCountNotNull = 0;
onCreateViewCountNull = 0;
onCreateViewCountNotNull = 0;
onViewCreatedCountNull = 0;
onViewCreatedCountNotNull = 0;
onViewReadyNewInstance = 0;
onViewReadyFirstTime = 0;
onViewReadyRotation = 0;
onViewReadyRestore = 0;
onViewReadyPopOut = 0;
onPushToBackStackCount = 0;
onPopAwayCount = 0;
onPoppedOutToFrontCount = 0;
onReturnForegroundCount = 0;
onOrientationChangedCount = 0;
onDestroyViewCount = 0;
onDestroyCount = 0;
Mockito.reset(lifeCycleMonitorMock);
}
}