/*
* Copyright 2012 Daniel Kurka
*
* 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.googlecode.mgwt.dom.client.recognizer.tap;
import com.google.gwt.event.dom.client.TouchCancelEvent;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HasHandlers;
import com.google.gwtmockito.GwtMockitoTestRunner;
import com.googlecode.mgwt.dom.client.recognizer.TimeProvider;
import com.googlecode.mgwt.helper.TouchTestUtil;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@RunWith(GwtMockitoTestRunner.class)
public class MultiTapRecognizerTest {
@Mock HasHandlers hasHandlers;
@Mock TimeProvider timeProvider;
@Captor ArgumentCaptor<GwtEvent<?>> eventCaptor;
@Before
public void setup() {
}
@Test
public void testExceptionInConstructor() {
try {
new MultiTapRecognizer(null, 1);
Assert.fail("expected exception did not occur");
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void testExceptionInConstructor1() {
try {
new MultiTapRecognizer(hasHandlers, 0);
Assert.fail("expected exception did not occur");
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void testExceptionInConstructor2() {
try {
new MultiTapRecognizer(hasHandlers, 1, -1);
Assert.fail("expected exception did not occur");
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void testExceptionInConstructor3() {
try {
new MultiTapRecognizer(hasHandlers, 1, 1, -1);
Assert.fail("expected exception did not occur");
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void testExceptionInConstructor4() {
try {
new MultiTapRecognizer(hasHandlers, 1, 1, 1, 0);
Assert.fail("expected exception did not occur");
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void testOneFingerSingleTap() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 1);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
}
@Test
public void testOneFingerSingleTapWithMove() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 1, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(1, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(1, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(2, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
}
@Test
public void testOneFingerSingleTapWithMoveTwice() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 1, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(1, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(1, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(2, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
reset(hasHandlers);
// second input
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(1, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(1, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(2, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
}
@Test
public void testTwoTapsWithOneFinger() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 2, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(3, 4));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(2, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(1, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(2, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
Assert.assertEquals(3, multiTapEvent.getTouchStarts().get(1).get(0).getPageX());
Assert.assertEquals(4, multiTapEvent.getTouchStarts().get(1).get(0).getPageY());
}
@Test
public void testTwoTapsWithOneFingerButMovetoofarOnSecondTap() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 2, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(3, 4));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(
3 + MultiTapRecognizer.DEFAULT_DISTANCE + 1, 4 + MultiTapRecognizer.DEFAULT_DISTANCE + 1));
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verifyNoMoreInteractions(hasHandlers);
}
@Test
public void testTwoTapsWithOneFingerButMovetoofarOnSecondTapAndThenTwoTaps() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 2, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(3, 4));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(
3 + MultiTapRecognizer.DEFAULT_DISTANCE + 1, 4 + MultiTapRecognizer.DEFAULT_DISTANCE + 1));
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(3, 4));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
Assert.assertNotNull(event);
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(1, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(2, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(1, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(2, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
Assert.assertEquals(3, multiTapEvent.getTouchStarts().get(1).get(0).getPageX());
Assert.assertEquals(4, multiTapEvent.getTouchStarts().get(1).get(0).getPageY());
}
@Test
public void testTimeoutWithTwoSingleFingerTaps() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 2, 10) {
@Override
TimeProvider getTimeProvider() {
return timeProvider;
}
};
when(timeProvider.getTime()).thenReturn(0L, MultiTapRecognizer.DEFAULT_TIME_IN_MS + 1L);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
}
@Test
public void testTwoTapsWithOneFingerInterrupedbyTouchcancel() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 1, 2, 10);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
recognizer.onTouchCancel(mock(TouchCancelEvent.class));
verifyNoMoreInteractions(hasHandlers);
}
@Test
public void testTwoFingerDownOneUpAndDownAgain() {
MultiTapRecognizer recognizer = new MultiTapRecognizer(hasHandlers, 2, 1, 10);
// first finger down
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(1, 2));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(2, 2));
verifyNoMoreInteractions(hasHandlers);
// second finger down and up
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(new int[] {1, 2, 3, 4}));
recognizer.onTouchEnd(mock(TouchEndEvent.class));
verifyNoMoreInteractions(hasHandlers);
// second finger down again and up
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(new int[] {1, 2, 3, 4}));
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verifyNoMoreInteractions(hasHandlers);
// last finger up
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verifyNoMoreInteractions(hasHandlers);
// lets test if we find a correct one now...
// first finger down
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(10, 20));
recognizer.onTouchMove(TouchTestUtil.createTouchMoveEvent(11, 22));
verifyNoMoreInteractions(hasHandlers);
// second finger down again and up
recognizer.onTouchStart(TouchTestUtil.createTouchStartEvent(new int[] {10, 20, 30, 40}));
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verifyNoMoreInteractions(hasHandlers);
// last finger up
recognizer.onTouchEnd(TouchTestUtil.createTouchEndEvent());
verify(hasHandlers).fireEvent(eventCaptor.capture());
GwtEvent<?> event = eventCaptor.getValue();
if (!(event instanceof MultiTapEvent)) {
Assert.fail("wrong event fired");
}
MultiTapEvent multiTapEvent = (MultiTapEvent) event;
Assert.assertEquals(2, multiTapEvent.getNumberOfFinders());
Assert.assertEquals(1, multiTapEvent.getNumberOfTabs());
Assert.assertEquals(10, multiTapEvent.getTouchStarts().get(0).get(0).getPageX());
Assert.assertEquals(20, multiTapEvent.getTouchStarts().get(0).get(0).getPageY());
Assert.assertEquals(30, multiTapEvent.getTouchStarts().get(0).get(1).getPageX());
Assert.assertEquals(40, multiTapEvent.getTouchStarts().get(0).get(1).getPageY());
}
}