blob: 9a5e46b030971c9d3a590fba287b53cba4888868 [file] [log] [blame]
package io.flutter.embedding.engine.mutatorsstack;
import static android.view.View.OnFocusChangeListener;
import static junit.framework.TestCase.*;
import static org.mockito.Mockito.*;
import android.graphics.Matrix;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import io.flutter.embedding.android.AndroidTouchProcessor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class FlutterMutatorViewTest {
@Test
public void canDragViews() {
final AndroidTouchProcessor touchProcessor = mock(AndroidTouchProcessor.class);
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext, 1.0f, touchProcessor);
final FlutterMutatorsStack mutatorStack = mock(FlutterMutatorsStack.class);
assertTrue(view.onInterceptTouchEvent(mock(MotionEvent.class)));
{
view.readyToDisplay(mutatorStack, /*left=*/ 1, /*top=*/ 2, /*width=*/ 0, /*height=*/ 0);
view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0));
final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
final Matrix screenMatrix = new Matrix();
screenMatrix.postTranslate(1, 2);
assertTrue(matrixCaptor.getValue().equals(screenMatrix));
}
reset(touchProcessor);
{
view.readyToDisplay(mutatorStack, /*left=*/ 3, /*top=*/ 4, /*width=*/ 0, /*height=*/ 0);
view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0.0f, 0.0f, 0));
final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
final Matrix screenMatrix = new Matrix();
screenMatrix.postTranslate(1, 2);
assertTrue(matrixCaptor.getValue().equals(screenMatrix));
}
reset(touchProcessor);
{
view.readyToDisplay(mutatorStack, /*left=*/ 5, /*top=*/ 6, /*width=*/ 0, /*height=*/ 0);
view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0.0f, 0.0f, 0));
final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
final Matrix screenMatrix = new Matrix();
screenMatrix.postTranslate(3, 4);
assertTrue(matrixCaptor.getValue().equals(screenMatrix));
}
reset(touchProcessor);
{
view.readyToDisplay(mutatorStack, /*left=*/ 7, /*top=*/ 8, /*width=*/ 0, /*height=*/ 0);
view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0));
final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
final Matrix screenMatrix = new Matrix();
screenMatrix.postTranslate(7, 8);
assertTrue(matrixCaptor.getValue().equals(screenMatrix));
}
}
@Test
public void childHasFocus_rootHasFocus() {
final View rootView = mock(View.class);
when(rootView.hasFocus()).thenReturn(true);
assertTrue(FlutterMutatorView.childHasFocus(rootView));
}
@Test
public void childHasFocus_rootDoesNotHaveFocus() {
final View rootView = mock(View.class);
when(rootView.hasFocus()).thenReturn(false);
assertFalse(FlutterMutatorView.childHasFocus(rootView));
}
@Test
public void childHasFocus_rootIsNull() {
assertFalse(FlutterMutatorView.childHasFocus(null));
}
@Test
public void childHasFocus_childHasFocus() {
final View childView = mock(View.class);
when(childView.hasFocus()).thenReturn(true);
final ViewGroup rootView = mock(ViewGroup.class);
when(rootView.getChildCount()).thenReturn(1);
when(rootView.getChildAt(0)).thenReturn(childView);
assertTrue(FlutterMutatorView.childHasFocus(rootView));
}
@Test
public void childHasFocus_childDoesNotHaveFocus() {
final View childView = mock(View.class);
when(childView.hasFocus()).thenReturn(false);
final ViewGroup rootView = mock(ViewGroup.class);
when(rootView.getChildCount()).thenReturn(1);
when(rootView.getChildAt(0)).thenReturn(childView);
assertFalse(FlutterMutatorView.childHasFocus(rootView));
}
@Test
public void focusChangeListener_hasFocus() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
when(viewTreeObserver.isAlive()).thenReturn(true);
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext) {
@Override
public ViewTreeObserver getViewTreeObserver() {
return viewTreeObserver;
}
@Override
public boolean hasFocus() {
return true;
}
};
final OnFocusChangeListener focusListener = mock(OnFocusChangeListener.class);
view.setOnDescendantFocusChangeListener(focusListener);
final ArgumentCaptor<ViewTreeObserver.OnGlobalFocusChangeListener> focusListenerCaptor =
ArgumentCaptor.forClass(ViewTreeObserver.OnGlobalFocusChangeListener.class);
verify(viewTreeObserver).addOnGlobalFocusChangeListener(focusListenerCaptor.capture());
focusListenerCaptor.getValue().onGlobalFocusChanged(null, null);
verify(focusListener).onFocusChange(view, true);
}
@Test
public void focusChangeListener_doesNotHaveFocus() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
when(viewTreeObserver.isAlive()).thenReturn(true);
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext) {
@Override
public ViewTreeObserver getViewTreeObserver() {
return viewTreeObserver;
}
@Override
public boolean hasFocus() {
return false;
}
};
final OnFocusChangeListener focusListener = mock(OnFocusChangeListener.class);
view.setOnDescendantFocusChangeListener(focusListener);
final ArgumentCaptor<ViewTreeObserver.OnGlobalFocusChangeListener> focusListenerCaptor =
ArgumentCaptor.forClass(ViewTreeObserver.OnGlobalFocusChangeListener.class);
verify(viewTreeObserver).addOnGlobalFocusChangeListener(focusListenerCaptor.capture());
focusListenerCaptor.getValue().onGlobalFocusChanged(null, null);
verify(focusListener).onFocusChange(view, false);
}
@Test
public void focusChangeListener_viewTreeObserverIsAliveFalseDoesNotThrow() {
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext) {
@Override
public ViewTreeObserver getViewTreeObserver() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
when(viewTreeObserver.isAlive()).thenReturn(false);
return viewTreeObserver;
}
};
view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
}
@Test
public void setOnDescendantFocusChangeListener_keepsSingleListener() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
when(viewTreeObserver.isAlive()).thenReturn(true);
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext) {
@Override
public ViewTreeObserver getViewTreeObserver() {
return viewTreeObserver;
}
};
assertNull(view.activeFocusListener);
view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
assertNotNull(view.activeFocusListener);
final ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener =
view.activeFocusListener;
view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
assertNotNull(view.activeFocusListener);
verify(viewTreeObserver, times(1)).removeOnGlobalFocusChangeListener(activeFocusListener);
}
@Test
public void unsetOnDescendantFocusChangeListener_removesActiveListener() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
when(viewTreeObserver.isAlive()).thenReturn(true);
final FlutterMutatorView view =
new FlutterMutatorView(RuntimeEnvironment.systemContext) {
@Override
public ViewTreeObserver getViewTreeObserver() {
return viewTreeObserver;
}
};
assertNull(view.activeFocusListener);
view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
assertNotNull(view.activeFocusListener);
final ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener =
view.activeFocusListener;
view.unsetOnDescendantFocusChangeListener();
assertNull(view.activeFocusListener);
view.unsetOnDescendantFocusChangeListener();
verify(viewTreeObserver, times(1)).removeOnGlobalFocusChangeListener(activeFocusListener);
}
}