pull/22/head
Mattia Iavarone 8 years ago
parent c72a566a93
commit 477ab1536e
  1. 4
      .travis.yml
  2. 6
      cameraview/build.gradle
  3. 7
      cameraview/src/androidTest/AndroidManifest.xml
  4. 151
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  5. 14
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  6. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  7. 5
      cameraview/src/main/views/com/otaliastudios/cameraview/GestureLayout.java

@ -35,10 +35,10 @@ before_script:
- adb shell input keyevent 82 & - adb shell input keyevent 82 &
script: script:
- ./gradlew clean testDebugUnitTest connectedCheck coverageReport - ./gradlew clean testDebugUnitTest connectedCheck mergedCoverageReport
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash) -s "*/build/reports/mergedCoverageReport/"
cache: cache:
directories: directories:

@ -171,14 +171,15 @@ artifacts {
apply plugin: 'jacoco' apply plugin: 'jacoco'
def reportsDirectory = "$buildDir/reports/"
jacoco { jacoco {
// Using a different version might get 0 coverage reports. // Using a different version might get 0 coverage reports.
// No time to investigate now. // No time to investigate now.
toolVersion = "0.7.6.201602180812" toolVersion = "0.7.6.201602180812"
reportsDir = file("$buildDir/reports/jacoco/merged/") reportsDir = file(reportsDirectory)
} }
task coverageReport(type: JacocoReport) { task mergedCoverageReport(type: JacocoReport) {
dependsOn "testDebugUnitTest" dependsOn "testDebugUnitTest"
dependsOn "connectedCheck" dependsOn "connectedCheck"
@ -202,6 +203,7 @@ task coverageReport(type: JacocoReport) {
reports.xml.enabled = true reports.xml.enabled = true
reports.html.enabled = true reports.html.enabled = true
reports.xml.destination = "$reportsDirectory/mergedCoverageReport/report.xml"
} }
//endregion //endregion

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.otaliastudios.cameraview">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>

@ -4,10 +4,12 @@ package com.otaliastudios.cameraview;
import android.app.Instrumentation; import android.app.Instrumentation;
import android.content.Context; import android.content.Context;
import android.hardware.Camera; import android.hardware.Camera;
import android.location.Location;
import android.os.Looper; import android.os.Looper;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -30,10 +32,15 @@ public class CameraViewTest {
private CameraView cameraView; private CameraView cameraView;
private MockCameraController mockController; private MockCameraController mockController;
private Preview mockPreview; private Preview mockPreview;
private boolean hasPermissions;
private void postOnUiSync(Runnable runnable) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
}
@Before @Before
public void setUp() { public void setUp() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { postOnUiSync(new Runnable() {
@Override @Override
public void run() { public void run() {
Context context = InstrumentationRegistry.getContext(); Context context = InstrumentationRegistry.getContext();
@ -49,6 +56,11 @@ public class CameraViewTest {
mockPreview = new MockPreview(context, container); mockPreview = new MockPreview(context, container);
return mockPreview; return mockPreview;
} }
@Override
protected boolean checkPermissions(SessionType sessionType) {
return hasPermissions;
}
}; };
} }
}); });
@ -59,12 +71,13 @@ public class CameraViewTest {
cameraView = null; cameraView = null;
mockController = null; mockController = null;
mockPreview = null; mockPreview = null;
hasPermissions = false;
} }
//region testDefaults //region testDefaults
@Test @Test
public void testNotStarted() { public void testNullBeforeStart() {
assertFalse(cameraView.isStarted()); assertFalse(cameraView.isStarted());
assertNull(cameraView.getCameraOptions()); assertNull(cameraView.getCameraOptions());
assertNull(cameraView.getExtraProperties()); assertNull(cameraView.getExtraProperties());
@ -96,6 +109,23 @@ public class CameraViewTest {
assertEquals(cameraView.getGestureAction(Gesture.SCROLL_VERTICAL), GestureAction.DEFAULT_SCROLL_VERTICAL); assertEquals(cameraView.getGestureAction(Gesture.SCROLL_VERTICAL), GestureAction.DEFAULT_SCROLL_VERTICAL);
} }
@Test
public void testStartWithPermissions() {
hasPermissions = true;
cameraView.start();
assertTrue(cameraView.isStarted());
cameraView.stop();
assertFalse(cameraView.isStarted());
}
@Test
public void testStartWithoutPermissions() {
hasPermissions = false;
cameraView.start();
assertFalse(cameraView.isStarted());
}
//endregion //endregion
//region testGesture //region testGesture
@ -145,6 +175,94 @@ public class CameraViewTest {
//endregion //endregion
//region testGestureAction
@Test
public void testGestureAction_capture() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() {
@Override
public void run() {
cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) {
public boolean onTouchEvent(MotionEvent event) { return true; }
};
cameraView.mTapGestureLayout.setGestureType(Gesture.TAP);
}
});
cameraView.mapGesture(Gesture.TAP, GestureAction.CAPTURE);
cameraView.dispatchTouchEvent(event);
assertTrue(mockController.mPictureCaptured);
}
@Test
public void testGestureAction_focus() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() {
@Override
public void run() {
cameraView.mTapGestureLayout = new TapGestureLayout(cameraView.getContext()) {
public boolean onTouchEvent(MotionEvent event) { return true; }
};
cameraView.mTapGestureLayout.setGestureType(Gesture.TAP);
}
});
mockController.mFocusStarted = false;
cameraView.mapGesture(Gesture.TAP, GestureAction.FOCUS);
cameraView.dispatchTouchEvent(event);
assertTrue(mockController.mFocusStarted);
// Try with FOCUS_WITH_MARKER
mockController.mFocusStarted = false;
cameraView.mapGesture(Gesture.TAP, GestureAction.FOCUS_WITH_MARKER);
cameraView.dispatchTouchEvent(event);
assertTrue(mockController.mFocusStarted);
}
@Test
public void testGestureAction_zoom() {
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() {
@Override
public void run() {
cameraView.mPinchGestureLayout = new PinchGestureLayout(cameraView.getContext()) {
public boolean onTouchEvent(MotionEvent event) { return true; }
};
cameraView.mPinchGestureLayout.setGestureType(Gesture.PINCH);
}
});
mockController.mZoomChanged = false;
cameraView.mapGesture(Gesture.PINCH, GestureAction.ZOOM);
cameraView.dispatchTouchEvent(event);
assertTrue(mockController.mZoomChanged);
}
@Test
public void testGestureAction_exposureCorrection() {
// This needs a valid CameraOptions value.
CameraOptions o = mock(CameraOptions.class);
when(o.getExposureCorrectionMinValue()).thenReturn(-10f);
when(o.getExposureCorrectionMaxValue()).thenReturn(10f);
mockController.setMockCameraOptions(o);
MotionEvent event = MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0);
postOnUiSync(new Runnable() {
@Override
public void run() {
cameraView.mScrollGestureLayout = new ScrollGestureLayout(cameraView.getContext()) {
public boolean onTouchEvent(MotionEvent event) { return true; }
};
cameraView.mScrollGestureLayout.setGestureType(Gesture.SCROLL_HORIZONTAL);
}
});
mockController.mExposureCorrectionChanged = false;
cameraView.mapGesture(Gesture.SCROLL_HORIZONTAL, GestureAction.EXPOSURE_CORRECTION);
cameraView.dispatchTouchEvent(event);
assertTrue(mockController.mExposureCorrectionChanged);
}
//endregion
//region testMeasure //region testMeasure
private void mockPreviewSize() { private void mockPreviewSize() {
@ -268,11 +386,34 @@ public class CameraViewTest {
//endregion //endregion
// TODO: test setLocation //region testLocation
// TODO: test touch events @Test
public void testSetLocation() {
cameraView.setLocation(50d, -50d);
assertEquals(50d, mockController.mLocation.getLatitude(), 0);
assertEquals(-50d, mockController.mLocation.getLongitude(), 0);
assertEquals(0, mockController.mLocation.getAltitude(), 0);
assertEquals("Unknown", mockController.mLocation.getProvider());
assertEquals(System.currentTimeMillis(), mockController.mLocation.getTime(), 1000f);
Location source = new Location("Provider");
source.setTime(5000);
source.setLatitude(10d);
source.setLongitude(-10d);
source.setAltitude(50d);
cameraView.setLocation(source);
Location other = mockController.mLocation;
assertEquals(10d, other.getLatitude(), 0d);
assertEquals(-10d, other.getLongitude(), 0d);
assertEquals(50d, other.getAltitude(), 0d);
assertEquals("Provider", other.getProvider());
assertEquals(5000, other.getTime());
}
//endregion
// TODO: test permissions and start() stop() isStarted() // TODO: test permissions
// TODO: test CameraCallbacks // TODO: test CameraCallbacks

@ -10,6 +10,12 @@ import java.io.File;
public class MockCameraController extends CameraController { public class MockCameraController extends CameraController {
Location mLocation;
boolean mPictureCaptured;
boolean mFocusStarted;
boolean mZoomChanged;
boolean mExposureCorrectionChanged;
MockCameraController(CameraView.CameraCallbacks callback, Preview preview) { MockCameraController(CameraView.CameraCallbacks callback, Preview preview) {
super(callback, preview); super(callback, preview);
} }
@ -24,21 +30,21 @@ public class MockCameraController extends CameraController {
@Override @Override
void onStart() { void onStart() {
} }
@Override @Override
void onStop() { void onStop() {
} }
@Override @Override
boolean setZoom(float zoom) { boolean setZoom(float zoom) {
mZoomChanged = true;
return true; return true;
} }
@Override @Override
boolean setExposureCorrection(float EVvalue) { boolean setExposureCorrection(float EVvalue) {
mExposureCorrectionChanged = true;
return true; return true;
} }
@ -74,11 +80,12 @@ public class MockCameraController extends CameraController {
@Override @Override
void setLocation(Location location) { void setLocation(Location location) {
mLocation = location;
} }
@Override @Override
boolean capturePicture() { boolean capturePicture() {
mPictureCaptured = true;
return true; return true;
} }
@ -109,6 +116,7 @@ public class MockCameraController extends CameraController {
@Override @Override
boolean startAutoFocus(@Nullable Gesture gesture, PointF point) { boolean startAutoFocus(@Nullable Gesture gesture, PointF point) {
mFocusStarted = true;
return true; return true;
} }

@ -498,7 +498,7 @@ public class CameraView extends FrameLayout {
* @return true if we can go on, false otherwise. * @return true if we can go on, false otherwise.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
private boolean checkPermissions(SessionType sessionType) { protected boolean checkPermissions(SessionType sessionType) {
checkPermissionsManifestOrThrow(sessionType); checkPermissionsManifestOrThrow(sessionType);
boolean api23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; boolean api23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
int cameraCheck, audioCheck; int cameraCheck, audioCheck;
@ -531,7 +531,7 @@ public class CameraView extends FrameLayout {
/** /**
* If mSessionType == SESSION_TYPE_VIDEO we will ask for RECORD_AUDIO permission. * If mSessionType == SESSION_TYPE_VIDEO we will ask for RECORD_AUDIO permission.
* If the developer did not add this to its manifest, throw and fire warnings. * If the developer did not add this to its manifest, throw and fire warnings.
* (Hoping this is not cought elsewhere... we should test). * (Hoping this is not caught elsewhere... we should test).
*/ */
private void checkPermissionsManifestOrThrow(SessionType sessionType) { private void checkPermissionsManifestOrThrow(SessionType sessionType) {
if (sessionType == SessionType.VIDEO) { if (sessionType == SessionType.VIDEO) {

@ -39,6 +39,11 @@ abstract class GestureLayout extends FrameLayout {
return mType; return mType;
} }
// For tests.
void setGestureType(Gesture type) {
mType = type;
}
public final PointF[] getPoints() { public final PointF[] getPoints() {
return mPoints; return mPoints;
} }

Loading…
Cancel
Save