From b9f36aa3272c1010b1c3270e625d466df271f736 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Wed, 6 Sep 2017 20:27:39 +0200 Subject: [PATCH] Gesture tests --- cameraview/build.gradle | 1 + .../otaliastudios/cameraview/BaseTest.java | 39 ++++++++ .../cameraview/CameraViewTest.java | 15 ++- .../cameraview/GestureLayoutTest.java | 47 +++++++++ .../cameraview/GridLinesLayoutTest.java | 78 +++++++++++++++ .../cameraview/OrientationHelperTest.java | 12 +-- .../cameraview/PinchGestureLayoutTest.java | 86 +++++++++++++++++ .../otaliastudios/cameraview/PreviewTest.java | 95 +++++++++---------- .../cameraview/ScrollGestureLayoutTest.java | 94 ++++++++++++++++++ .../cameraview/TapGestureLayoutTest.java | 73 ++++++++++++++ .../cameraview/TestActivity.java | 46 +++++++++ .../cameraview/GridLinesLayout.java | 10 +- .../cameraview/PinchGestureLayout.java | 2 +- .../cameraview/TapGestureLayout.java | 4 +- 14 files changed, 533 insertions(+), 69 deletions(-) create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java create mode 100644 cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java diff --git a/cameraview/build.gradle b/cameraview/build.gradle index f212b60f..987db39e 100644 --- a/cameraview/build.gradle +++ b/cameraview/build.gradle @@ -46,6 +46,7 @@ dependencies { androidTestCompile 'com.android.support.test:rules:1.0.1' androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' + androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1' compile "com.android.support:exifinterface:$supportLibVersion" compile "com.android.support:support-annotations:$supportLibVersion" diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java new file mode 100644 index 00000000..d16d68c0 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/BaseTest.java @@ -0,0 +1,39 @@ +package com.otaliastudios.cameraview; + + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.support.test.InstrumentationRegistry; +import android.support.test.rule.ActivityTestRule; +import android.view.View; + +import org.junit.Rule; + +public class BaseTest { + + public static void ui(Runnable runnable) { + InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable); + } + + public static void uiAsync(Runnable runnable) { + new Handler(Looper.getMainLooper()).post(runnable); + } + + public static Context context() { + return InstrumentationRegistry.getInstrumentation().getContext(); + } + + public static void uiRequestLayout(final View view) { + ui(new Runnable() { + @Override + public void run() { + view.requestLayout(); + } + }); + } + + public static void waitUi() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java index 98c29927..9e2f645d 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java @@ -27,20 +27,17 @@ import static android.view.ViewGroup.LayoutParams.*; @RunWith(AndroidJUnit4.class) @MediumTest -public class CameraViewTest { +public class CameraViewTest extends BaseTest { private CameraView cameraView; private MockCameraController mockController; private Preview mockPreview; private boolean hasPermissions; - private void postOnUiSync(Runnable runnable) { - InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable); - } @Before public void setUp() { - postOnUiSync(new Runnable() { + ui(new Runnable() { @Override public void run() { Context context = InstrumentationRegistry.getContext(); @@ -180,7 +177,7 @@ public class CameraViewTest { @Test public void testGestureAction_capture() { MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); - postOnUiSync(new Runnable() { + ui(new Runnable() { @Override public void run() { cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) { @@ -198,7 +195,7 @@ public class CameraViewTest { @Test public void testGestureAction_focus() { MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); - postOnUiSync(new Runnable() { + ui(new Runnable() { @Override public void run() { cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) { @@ -222,7 +219,7 @@ public class CameraViewTest { @Test public void testGestureAction_zoom() { MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); - postOnUiSync(new Runnable() { + ui(new Runnable() { @Override public void run() { cameraView.mPinchGestureLayout = new PinchGestureLayout(cameraView.getContext()) { @@ -246,7 +243,7 @@ public class CameraViewTest { mockController.setMockCameraOptions(o); MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0); - postOnUiSync(new Runnable() { + ui(new Runnable() { @Override public void run() { cameraView.mScrollGestureLayout = new ScrollGestureLayout(cameraView.getContext()) { diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java new file mode 100644 index 00000000..5f2724a3 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GestureLayoutTest.java @@ -0,0 +1,47 @@ +package com.otaliastudios.cameraview; + + +import android.annotation.TargetApi; +import android.content.Context; +import android.support.test.rule.ActivityTestRule; +import android.view.MotionEvent; +import android.view.View; + +import org.junit.Before; +import org.junit.Rule; + +@TargetApi(17) +public abstract class GestureLayoutTest extends BaseTest { + + protected abstract T create(Context context); + + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(TestActivity.class); + + protected T layout; + protected Task touch; + + @Before + public void setUp() { + ui(new Runnable() { + @Override + public void run() { + TestActivity a = rule.getActivity(); + layout = create(a); + layout.enable(true); + a.inflate(layout); + + touch = new Task<>(); + layout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + boolean found = layout.onTouchEvent(motionEvent); + if (found) touch.end(layout.getGestureType()); + return true; + } + }); + layout.setId(View.generateViewId()); + } + }); + } +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java new file mode 100644 index 00000000..8869ce10 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/GridLinesLayoutTest.java @@ -0,0 +1,78 @@ +package com.otaliastudios.cameraview; + + +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.mockito.Mockito.*; + +@RunWith(AndroidJUnit4.class) +@MediumTest +public class GridLinesLayoutTest extends BaseTest { + + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(TestActivity.class); + + private GridLinesLayout layout; + + @Before + public void setUp() { + ui(new Runnable() { + @Override + public void run() { + TestActivity a = rule.getActivity(); + layout = new GridLinesLayout(a); + layout.setGridMode(Grid.OFF); + a.getContentView().addView(layout); + layout.vert = mock(ColorDrawable.class); + layout.horiz = mock(ColorDrawable.class); + } + }); + } + + @Test + public void testOff() { + layout.drawTask.listen(); + layout.setGridMode(Grid.OFF); + layout.drawTask.await(); + verify(layout.vert, never()).draw(any(Canvas.class)); + verify(layout.horiz, never()).draw(any(Canvas.class)); + } + + @Test + public void test3x3() { + layout.drawTask.listen(); + layout.setGridMode(Grid.DRAW_3X3); + layout.drawTask.await(); + verify(layout.vert, times(2)).draw(any(Canvas.class)); + verify(layout.horiz, times(2)).draw(any(Canvas.class)); + } + + @Test + public void testPhi() { + layout.drawTask.listen(); + layout.setGridMode(Grid.DRAW_PHI); + layout.drawTask.await(); + verify(layout.vert, times(2)).draw(any(Canvas.class)); + verify(layout.horiz, times(2)).draw(any(Canvas.class)); + } + + @Test + public void test4x4() { + layout.drawTask.listen(); + layout.setGridMode(Grid.DRAW_4X4); + layout.drawTask.await(); + verify(layout.vert, times(3)).draw(any(Canvas.class)); + verify(layout.horiz, times(3)).draw(any(Canvas.class)); + } + +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java index 1b496680..19a6aa83 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/OrientationHelperTest.java @@ -19,18 +19,18 @@ import static org.mockito.Mockito.*; @RunWith(AndroidJUnit4.class) @SmallTest -public class OrientationHelperTest { +public class OrientationHelperTest extends BaseTest { private OrientationHelper helper; private OrientationHelper.Callbacks callbacks; @Before public void setUp() { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + ui(new Runnable() { @Override public void run() { callbacks = mock(OrientationHelper.Callbacks.class); - helper = new OrientationHelper(InstrumentationRegistry.getContext(), callbacks); + helper = new OrientationHelper(context(), callbacks); } }); } @@ -46,12 +46,12 @@ public class OrientationHelperTest { assertNotNull(helper.mListener); assertNull(helper.mDisplay); - helper.enable(InstrumentationRegistry.getContext()); + helper.enable(context()); assertNotNull(helper.mListener); assertNotNull(helper.mDisplay); // Ensure nothing bad if called twice. - helper.enable(InstrumentationRegistry.getContext()); + helper.enable(context()); assertNotNull(helper.mListener); assertNotNull(helper.mDisplay); @@ -64,7 +64,7 @@ public class OrientationHelperTest { @Test public void testRotation() { - helper.enable(InstrumentationRegistry.getContext()); + helper.enable(context()); reset(callbacks); // Reset counts. helper.mListener.onOrientationChanged(OrientationEventListener.ORIENTATION_UNKNOWN); diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java new file mode 100644 index 00000000..df6b3376 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PinchGestureLayoutTest.java @@ -0,0 +1,86 @@ +package com.otaliastudios.cameraview; + + +import android.content.Context; +import android.support.test.espresso.Espresso; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.espresso.action.CoordinatesProvider; +import android.support.test.espresso.action.GeneralLocation; +import android.support.test.espresso.action.GeneralSwipeAction; +import android.support.test.espresso.action.MotionEvents; +import android.support.test.espresso.action.PrecisionDescriber; +import android.support.test.espresso.action.Press; +import android.support.test.espresso.action.Swipe; +import android.support.test.espresso.action.ViewActions; +import android.support.test.espresso.assertion.ViewAssertions; +import android.support.test.espresso.matcher.ViewMatchers; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.View; + +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class PinchGestureLayoutTest extends GestureLayoutTest { + + @Override + protected PinchGestureLayout create(Context context) { + return new PinchGestureLayout(context); + } + + @Test + public void testDefaults() { + assertEquals(layout.getGestureType(), Gesture.PINCH); + assertEquals(layout.getPoints().length, 2); + assertEquals(layout.getPoints()[0].x, 0, 0); + assertEquals(layout.getPoints()[0].y, 0, 0); + assertEquals(layout.getPoints()[1].x, 0, 0); + assertEquals(layout.getPoints()[1].y, 0, 0); + } + + // TODO: test pinch open + // TODO: test pinch close + // TODO: test pinch disabled + + // Possible approach: mimic pinch gesture and let espresso test. + // Too lazy to do this now, but it's possible. + // https://stackoverflow.com/questions/11523423/how-to-generate-zoom-pinch-gesture-for-testing-for-android + + public abstract class PinchViewAction implements ViewAction { + } + + private void testPinch(ViewAction action, boolean increasing) { + touch.listen(); + touch.start(); + onView(withId(layout.getId())).perform(action); + Gesture found = touch.await(10000, TimeUnit.MILLISECONDS); + assertNotNull(found); + + // How will this move our parameter? + float curr = 0.5f, min = 0f, max = 1f; + float newValue = layout.scaleValue(curr, min, max); + if (increasing) { + assertTrue(newValue > curr); + assertTrue(newValue <= max); + } else { + assertTrue(newValue < curr); + assertTrue(newValue >= min); + } + } +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PreviewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PreviewTest.java index ac9aa6fb..f375c06c 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PreviewTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/PreviewTest.java @@ -2,58 +2,61 @@ package com.otaliastudios.cameraview; import android.content.Context; -import android.support.test.InstrumentationRegistry; import android.support.test.rule.ActivityTestRule; import android.view.ViewGroup; -import android.widget.FrameLayout; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; -import java.util.concurrent.Semaphore; import static org.junit.Assert.*; import static org.mockito.Mockito.*; -public abstract class PreviewTest { +public abstract class PreviewTest extends BaseTest { protected abstract Preview createPreview(Context context, ViewGroup parent); - private Preview preview; - private ViewGroup parent; - private Preview.SurfaceCallback callback; - private Size surfaceSize = new Size(1000, 1000); - @Rule public ActivityTestRule rule = new ActivityTestRule<>(TestActivity.class); + private Preview preview; + private Preview.SurfaceCallback callback; + private Size surfaceSize; + private Task surfaceAvailability; + @Before public void setUp() { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + ui(new Runnable() { @Override public void run() { - Context context = rule.getActivity(); + TestActivity a = rule.getActivity(); + preview = createPreview(a, a.getContentView()); + surfaceSize = a.getContentSize(); - // Using a parent so we know its size. - parent = new FrameLayout(context); - parent.setLayoutParams(new ViewGroup.LayoutParams( - surfaceSize.getWidth(), surfaceSize.getHeight())); - preview = createPreview(context, parent); callback = mock(Preview.SurfaceCallback.class); preview.setSurfaceCallback(callback); - // Add all to a decor view and to the activity. - FrameLayout decor = new FrameLayout(context); - decor.addView(parent); - rule.getActivity().setContentView(decor); + surfaceAvailability = new Task<>(); + surfaceAvailability.listen(); + surfaceAvailability.start(); + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + surfaceAvailability.end(null); + return null; + } + }).when(callback).onSurfaceAvailable(); } }); } @Test public void testDefaults() { + ViewGroup parent = rule.getActivity().getContentView(); assertNotNull(preview.getView()); assertEquals(parent.getChildAt(0), preview.getView()); assertNotNull(preview.getOutputClass()); @@ -67,56 +70,52 @@ public abstract class PreviewTest { } @Test - public void testSurfaceSize() { - preview.onSurfaceAvailable(500, 1000); - assertEquals(500, preview.getSurfaceSize().getWidth()); - assertEquals(1000, preview.getSurfaceSize().getHeight()); - - preview.onSurfaceSizeChanged(50, 100); - assertEquals(50, preview.getSurfaceSize().getWidth()); - assertEquals(100, preview.getSurfaceSize().getHeight()); + public void testSurfaceAvailable() { + surfaceAvailability.await(); - preview.onSurfaceDestroyed(); - assertEquals(0, preview.getSurfaceSize().getWidth()); - assertEquals(0, preview.getSurfaceSize().getHeight()); + // Wait for surface to be available. + verify(callback, times(1)).onSurfaceAvailable(); + assertEquals(surfaceSize.getWidth(), preview.getSurfaceSize().getWidth()); + assertEquals(surfaceSize.getHeight(), preview.getSurfaceSize().getHeight()); } @Test - public void testCallbacks() { - preview.onSurfaceAvailable(500, 1000); - verify(callback, times(1)).onSurfaceAvailable(); + public void testSurfaceDestroyed() { + surfaceAvailability.await(); - preview.onSurfaceSizeChanged(50, 100); - verify(callback, times(1)).onSurfaceChanged(); + // Trigger a destroy. + ui(new Runnable() { + @Override + public void run() { + rule.getActivity().getContentView().removeAllViews(); + } + }); + assertEquals(0, preview.getSurfaceSize().getWidth()); + assertEquals(0, preview.getSurfaceSize().getHeight()); } @Test public void testCropCenter() throws Exception { - Task cropTask = preview.mCropTask; - - // If aspect ratio is different, there should be a crop. - preview.onSurfaceAvailable( - surfaceSize.getWidth(), - surfaceSize.getHeight()); + surfaceAvailability.await(); // Not cropping. - cropTask.listen(); + preview.mCropTask.listen(); preview.setDesiredSize(100, 100); // Wait... - cropTask.await(); + preview.mCropTask.await(); assertEquals(100f / 100f, getScaledAspectRatio(), 0.01f); assertFalse(preview.isCropping()); // Cropping. - cropTask.listen(); + preview.mCropTask.listen(); preview.setDesiredSize(160, 50); // Wait... - cropTask.await(); + preview.mCropTask.await(); assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f); assertTrue(preview.isCropping()); // Not cropping. - cropTask.listen(); + preview.mCropTask.listen(); preview.onSurfaceSizeChanged(1600, 500); // Wait... - cropTask.await(); + preview.mCropTask.await(); assertEquals(160f / 50f, getScaledAspectRatio(), 0.01f); assertFalse(preview.isCropping()); } diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java new file mode 100644 index 00000000..bd272439 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/ScrollGestureLayoutTest.java @@ -0,0 +1,94 @@ +package com.otaliastudios.cameraview; + + +import android.content.Context; +import android.support.test.espresso.ViewAction; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.swipeDown; +import static android.support.test.espresso.action.ViewActions.swipeLeft; +import static android.support.test.espresso.action.ViewActions.swipeRight; +import static android.support.test.espresso.action.ViewActions.swipeUp; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ScrollGestureLayoutTest extends GestureLayoutTest { + + @Override + protected ScrollGestureLayout create(Context context) { + return new ScrollGestureLayout(context); + } + + @Test + public void testDefaults() { + assertNull(layout.getGestureType()); + assertEquals(layout.getPoints().length, 2); + assertEquals(layout.getPoints()[0].x, 0, 0); + assertEquals(layout.getPoints()[0].y, 0, 0); + assertEquals(layout.getPoints()[1].x, 0, 0); + assertEquals(layout.getPoints()[1].y, 0, 0); + } + + @Test + public void testScrollDisabled() { + layout.enable(false); + touch.listen(); + touch.start(); + onView(withId(layout.getId())).perform(swipeUp()); + Gesture found = touch.await(500, TimeUnit.MILLISECONDS); + assertNull(found); + } + + private void testScroll(ViewAction scroll, Gesture expected, boolean increasing) { + touch.listen(); + touch.start(); + onView(withId(layout.getId())).perform(scroll); + Gesture found = touch.await(500, TimeUnit.MILLISECONDS); + assertEquals(found, expected); + + // How will this move our parameter? + float curr = 0.5f, min = 0f, max = 1f; + float newValue = layout.scaleValue(curr, min, max); + if (increasing) { + assertTrue(newValue > curr); + assertTrue(newValue <= max); + } else { + assertTrue(newValue < curr); + assertTrue(newValue >= min); + } + } + + @Test + public void testScrollLeft() { + testScroll(swipeLeft(), Gesture.SCROLL_HORIZONTAL, false); + } + + @Test + public void testScrollRight() { + testScroll(swipeRight(), Gesture.SCROLL_HORIZONTAL, true); + } + + @Test + public void testScrollUp() { + testScroll(swipeUp(), Gesture.SCROLL_VERTICAL, true); + } + + @Test + public void testScrollDown() { + testScroll(swipeDown(), Gesture.SCROLL_VERTICAL, false); + } + + +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java new file mode 100644 index 00000000..8e403402 --- /dev/null +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TapGestureLayoutTest.java @@ -0,0 +1,73 @@ +package com.otaliastudios.cameraview; + + +import android.content.Context; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +import static android.support.test.espresso.Espresso.*; +import static android.support.test.espresso.matcher.ViewMatchers.*; +import static android.support.test.espresso.action.ViewActions.*; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class TapGestureLayoutTest extends GestureLayoutTest { + + @Override + protected TapGestureLayout create(Context context) { + return new TapGestureLayout(context); + } + + @Test + public void testDefaults() { + assertNull(layout.getGestureType()); + assertEquals(layout.getPoints().length, 1); + assertEquals(layout.getPoints()[0].x, 0, 0); + assertEquals(layout.getPoints()[0].y, 0, 0); + } + + @Test + public void testTap() { + touch.listen(); + touch.start(); + Size size = rule.getActivity().getContentSize(); + int x = (int) (size.getWidth() / 2f); + int y = (int) (size.getHeight() / 2f); + onView(withId(layout.getId())).perform(click(x, y)); + Gesture found = touch.await(500, TimeUnit.MILLISECONDS); + assertEquals(found, Gesture.TAP); + assertEquals(layout.getPoints()[0].x, x, 1); + assertEquals(layout.getPoints()[0].y, y, 1); + } + + @Test + public void testTapWhileDisabled() { + layout.enable(false); + touch.listen(); + touch.start(); + Size size = rule.getActivity().getContentSize(); + int x = (int) (size.getWidth() / 2f); + int y = (int) (size.getHeight() / 2f); + onView(withId(layout.getId())).perform(click(x, y)); + Gesture found = touch.await(500, TimeUnit.MILLISECONDS); + assertNull(found); + } + + @Test + public void testLongTap() { + touch.listen(); + touch.start(); + Size size = rule.getActivity().getContentSize(); + int x = (int) (size.getWidth() / 2f); + int y = (int) (size.getHeight() / 2f); + onView(withId(layout.getId())).perform(longClick()); + Gesture found = touch.await(500, TimeUnit.MILLISECONDS); + assertEquals(found, Gesture.LONG_TAP); + } +} diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TestActivity.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TestActivity.java index 8108c7d3..a2b5ca13 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TestActivity.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/TestActivity.java @@ -2,6 +2,52 @@ package com.otaliastudios.cameraview; import android.app.Activity; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.support.annotation.Nullable; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import static android.view.ViewGroup.LayoutParams.*; public class TestActivity extends Activity { + + private ViewGroup content; + private Size contentSize = new Size(1000, 1000); + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Match parent decor view. + FrameLayout root = new FrameLayout(this); + root.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); + + // Inner content view with fixed size. + content = new FrameLayout(this); + content.setLayoutParams(new ViewGroup.LayoutParams( + contentSize.getWidth(), contentSize.getHeight())); + + // Add. + root.addView(content); + setContentView(root); + } + + public Size getContentSize() { + return contentSize; + } + + public ViewGroup getContentView() { + return content; + } + + public void inflate(View child) { + inflate(child, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); + } + + public void inflate(View child, ViewGroup.LayoutParams params) { + content.addView(child, params); + content.requestLayout(); + } } diff --git a/cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java b/cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java index d8f16e4f..0d7784ea 100644 --- a/cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java +++ b/cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java @@ -16,10 +16,12 @@ class GridLinesLayout extends View { private Grid gridMode; - private final Drawable horiz; - private final Drawable vert; + Drawable horiz; + Drawable vert; private final float width; + Task drawTask = new Task<>(); + private final static float GOLDEN_RATIO_INV = 0.61803398874989f; public GridLinesLayout(@NonNull Context context) { @@ -46,7 +48,7 @@ class GridLinesLayout extends View { public void setGridMode(Grid gridMode) { this.gridMode = gridMode; - invalidate(); + postInvalidate(); } private int getLineCount() { @@ -75,6 +77,7 @@ class GridLinesLayout extends View { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); + drawTask.start(); int count = getLineCount(); for (int n = 0; n < count; n++) { float pos = getLinePosition(n); @@ -89,5 +92,6 @@ class GridLinesLayout extends View { vert.draw(canvas); canvas.translate(- pos * getWidth(), 0); } + drawTask.end(null); } } diff --git a/cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java b/cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java index 574c5e5a..08c0cd62 100644 --- a/cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java +++ b/cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java @@ -14,7 +14,7 @@ class PinchGestureLayout extends GestureLayout { private final static float ADD_SENSITIVITY = 2f; - private ScaleGestureDetector mDetector; + ScaleGestureDetector mDetector; private boolean mNotify; private float mAdditionFactor = 0; diff --git a/cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java b/cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java index 541dd5fd..bf2965cf 100644 --- a/cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java +++ b/cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java @@ -58,8 +58,8 @@ class TapGestureLayout extends GestureLayout { // Views to draw the focus marker. LayoutInflater.from(getContext()).inflate(R.layout.layout_focus_marker, this); - mFocusMarkerContainer = (FrameLayout) findViewById(R.id.focusMarkerContainer); - mFocusMarkerFill = (ImageView) findViewById(R.id.fill); + mFocusMarkerContainer = findViewById(R.id.focusMarkerContainer); + mFocusMarkerFill = findViewById(R.id.fill); }