Improve coverage (#507)
* Do not use ViewCompat * Remove TODOs, improve logging * SizeSelectorParser and CameraUtils tests * DefaultAutoFOcusMarkerTest * MarkerParserTest and improve MarkerLayoutTest * Add MediaEncoderEngine comments * Add ExifHelper test * ImageHelper test * More internal/utils testspull/513/head
parent
6962744d4f
commit
1318b7d10b
@ -0,0 +1,55 @@ |
|||||||
|
package com.otaliastudios.cameraview.internal.utils; |
||||||
|
|
||||||
|
|
||||||
|
import android.media.CamcorderProfile; |
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
|
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
import com.otaliastudios.cameraview.CameraUtils; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class CamcorderProfilesTest extends BaseTest { |
||||||
|
|
||||||
|
private String getCameraId() { |
||||||
|
if (CameraUtils.hasCameras(getContext())) { |
||||||
|
return "0"; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testInvalidCameraReturnsLowest() { |
||||||
|
CamcorderProfile invalid = CamcorderProfiles.get("invalid", new Size(100, 100)); |
||||||
|
CamcorderProfile lowest = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); |
||||||
|
assertEquals(lowest.videoFrameWidth, invalid.videoFrameWidth); |
||||||
|
assertEquals(lowest.videoFrameHeight, invalid.videoFrameHeight); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGet() { |
||||||
|
String cameraId = getCameraId(); |
||||||
|
if (cameraId == null) return; |
||||||
|
int cameraIdInt = Integer.parseInt(cameraId); |
||||||
|
|
||||||
|
// Not much we can test. Let's just ask for lowest and highest.
|
||||||
|
CamcorderProfile low = CamcorderProfiles.get(cameraId, new Size(1, 1)); |
||||||
|
CamcorderProfile high = CamcorderProfiles.get(cameraId, new Size(Integer.MAX_VALUE, Integer.MAX_VALUE)); |
||||||
|
|
||||||
|
// Compare with lowest
|
||||||
|
CamcorderProfile lowest = CamcorderProfile.get(cameraIdInt, CamcorderProfile.QUALITY_LOW); |
||||||
|
CamcorderProfile highest = CamcorderProfile.get(cameraIdInt, CamcorderProfile.QUALITY_HIGH); |
||||||
|
assertEquals(lowest.videoFrameWidth, low.videoFrameWidth); |
||||||
|
assertEquals(lowest.videoFrameHeight, low.videoFrameHeight); |
||||||
|
assertEquals(highest.videoFrameWidth, high.videoFrameWidth); |
||||||
|
assertEquals(highest.videoFrameHeight, high.videoFrameHeight); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,102 @@ |
|||||||
|
package com.otaliastudios.cameraview.internal.utils; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.graphics.Canvas; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.ImageFormat; |
||||||
|
import android.graphics.Paint; |
||||||
|
import android.graphics.PorterDuff; |
||||||
|
import android.graphics.Rect; |
||||||
|
import android.graphics.YuvImage; |
||||||
|
import android.media.Image; |
||||||
|
import android.media.ImageReader; |
||||||
|
import android.opengl.GLES20; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Looper; |
||||||
|
import android.view.Surface; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
|
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
import com.otaliastudios.cameraview.internal.egl.EglCore; |
||||||
|
import com.otaliastudios.cameraview.internal.egl.EglViewport; |
||||||
|
import com.otaliastudios.cameraview.internal.egl.EglWindowSurface; |
||||||
|
import com.otaliastudios.cameraview.size.AspectRatio; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNotEquals; |
||||||
|
import static org.junit.Assert.assertNotNull; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class ImageHelperTest extends BaseTest { |
||||||
|
|
||||||
|
@NonNull |
||||||
|
private Image getImage() { |
||||||
|
ImageReader reader = ImageReader.newInstance(100, 100, ImageFormat.YUV_420_888, 1); |
||||||
|
Surface readerSurface = reader.getSurface(); |
||||||
|
final Op<Image> imageOp = new Op<>(true); |
||||||
|
reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { |
||||||
|
@Override |
||||||
|
public void onImageAvailable(ImageReader reader) { |
||||||
|
Image image = reader.acquireLatestImage(); |
||||||
|
if (image != null) imageOp.end(image); |
||||||
|
} |
||||||
|
}, new Handler(Looper.getMainLooper())); |
||||||
|
|
||||||
|
// Write on reader surface.
|
||||||
|
Canvas readerCanvas = readerSurface.lockCanvas(null); |
||||||
|
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); |
||||||
|
paint.setColor(Color.RED); |
||||||
|
readerCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY); |
||||||
|
readerCanvas.drawCircle(50, 50, 50, paint); |
||||||
|
readerSurface.unlockCanvasAndPost(readerCanvas); |
||||||
|
|
||||||
|
// Wait
|
||||||
|
Image image = imageOp.await(5000); |
||||||
|
assertNotNull(image); |
||||||
|
return image; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testImage() { |
||||||
|
Image image = getImage(); |
||||||
|
int width = image.getWidth(); |
||||||
|
int height = image.getHeight(); |
||||||
|
int bitsPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.NV21); |
||||||
|
int sizeBits = width * height * bitsPerPixel; |
||||||
|
int sizeBytes = (int) Math.ceil(sizeBits / 8.0d); |
||||||
|
byte[] bytes = new byte[sizeBytes]; |
||||||
|
ImageHelper.convertToNV21(image, bytes); |
||||||
|
image.close(); |
||||||
|
|
||||||
|
// Read the image
|
||||||
|
YuvImage yuvImage = new YuvImage(bytes, ImageFormat.NV21, width, height, null); |
||||||
|
ByteArrayOutputStream jpegStream = new ByteArrayOutputStream(); |
||||||
|
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, jpegStream); |
||||||
|
byte[] jpegByteArray = jpegStream.toByteArray(); |
||||||
|
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.length); |
||||||
|
assertNotNull(bitmap); |
||||||
|
|
||||||
|
// Wanted to do assertions on the color here but it doesn't work. There must be an issue
|
||||||
|
// with how we are drawing the image in this test, since in real camera, the algorithm works well.
|
||||||
|
// So for now let's just test that nothing crashes during this process.
|
||||||
|
// int color = bitmap.getPixel(bitmap.getWidth() - 1, bitmap.getHeight() - 1);
|
||||||
|
// assertEquals(Color.red(color), 255, 5);
|
||||||
|
// assertEquals(Color.green(color), 0, 5);
|
||||||
|
// assertEquals(Color.blue(color), 0, 5);
|
||||||
|
// assertEquals(Color.alpha(color), 0, 5);
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package com.otaliastudios.cameraview.internal.utils; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.ImageFormat; |
||||||
|
import android.graphics.YuvImage; |
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
|
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNotNull; |
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class RotationHelperTest extends BaseTest { |
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class) |
||||||
|
public void testInvalidRotation1() { |
||||||
|
RotationHelper.rotate(new byte[10], new Size(1, 1), -1); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class) |
||||||
|
public void testInvalidRotation2() { |
||||||
|
RotationHelper.rotate(new byte[10], new Size(1, 1), -90); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class) |
||||||
|
public void testInvalidRotation3() { |
||||||
|
RotationHelper.rotate(new byte[10], new Size(1, 1), 360); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRotate() { |
||||||
|
// Just test that nothing happens.
|
||||||
|
Size inputSize = new Size(160, 90); |
||||||
|
int inputSizeBits = inputSize.getWidth() * inputSize.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.NV21); |
||||||
|
int inputSizeBytes = (int) Math.ceil(inputSizeBits / 8.0d); |
||||||
|
byte[] input = new byte[inputSizeBytes]; |
||||||
|
byte[] output = RotationHelper.rotate(input, inputSize, 90); |
||||||
|
assertEquals(input.length, output.length); |
||||||
|
|
||||||
|
Size outputSize = inputSize.flip(); |
||||||
|
YuvImage image = new YuvImage(output, ImageFormat.NV21, outputSize.getWidth(), outputSize.getHeight(), null); |
||||||
|
assertNotNull(image); |
||||||
|
} |
||||||
|
} |
@ -1,41 +1,229 @@ |
|||||||
package com.otaliastudios.cameraview.internal.utils; |
package com.otaliastudios.cameraview.internal.utils; |
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.gms.tasks.Task; |
||||||
|
import com.google.android.gms.tasks.Tasks; |
||||||
import com.otaliastudios.cameraview.BaseTest; |
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4; |
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
import androidx.test.filters.SmallTest; |
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
import org.junit.Test; |
import org.junit.Test; |
||||||
import org.junit.runner.RunWith; |
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import java.util.concurrent.Callable; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
import java.util.concurrent.Executor; |
||||||
|
|
||||||
import static org.junit.Assert.*; |
import static org.junit.Assert.*; |
||||||
|
import static org.junit.Assert.assertNotNull; |
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class) |
@RunWith(AndroidJUnit4.class) |
||||||
@SmallTest |
@SmallTest |
||||||
public class WorkerHandlerTest extends BaseTest { |
public class WorkerHandlerTest extends BaseTest { |
||||||
|
|
||||||
@Test |
@Test |
||||||
public void testCache() { |
public void testGetFromCache() { |
||||||
WorkerHandler w1 = WorkerHandler.get("handler1"); |
WorkerHandler first = WorkerHandler.get("first"); |
||||||
WorkerHandler w1a = WorkerHandler.get("handler1"); |
WorkerHandler second = WorkerHandler.get("first"); |
||||||
WorkerHandler w2 = WorkerHandler.get("handler2"); |
assertSame(first, second); |
||||||
assertSame(w1, w1a); |
|
||||||
assertNotSame(w1, w2); |
|
||||||
} |
} |
||||||
|
|
||||||
@Test |
@Test |
||||||
public void testStaticRun() { |
public void testGetAnother() { |
||||||
final Op<Boolean> op = new Op<>(true); |
WorkerHandler first = WorkerHandler.get("first"); |
||||||
Runnable action = new Runnable() { |
WorkerHandler second = WorkerHandler.get("second"); |
||||||
|
assertNotSame(first, second); |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
private Runnable getRunnableForOp(final @NonNull Op<Boolean> op) { |
||||||
|
return new Runnable() { |
||||||
@Override |
@Override |
||||||
public void run() { |
public void run() { |
||||||
op.end(true); |
op.end(true); |
||||||
} |
} |
||||||
}; |
}; |
||||||
WorkerHandler.execute(action); |
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
private Callable<Boolean> getCallableForOp(final @NonNull Op<Boolean> op) { |
||||||
|
return new Callable<Boolean>() { |
||||||
|
@Override |
||||||
|
public Boolean call() { |
||||||
|
op.end(true); |
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
private Callable<Void> getThrowCallable() { |
||||||
|
return new Callable<Void>() { |
||||||
|
@Override |
||||||
|
public Void call() { |
||||||
|
throw new RuntimeException("Fake error"); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private void waitOp(@NonNull Op<Boolean> op) { |
||||||
Boolean result = op.await(500); |
Boolean result = op.await(500); |
||||||
assertNotNull(result); |
assertNotNull(result); |
||||||
assertTrue(result); |
assertTrue(result); |
||||||
} |
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testFallbackExecute() { |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
WorkerHandler.execute(getRunnableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPostRunnable() { |
||||||
|
WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.post(getRunnableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPostCallable() { |
||||||
|
WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.post(getCallableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPostCallable_throws() { |
||||||
|
WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
Task<Void> task = handler.post(getThrowCallable()); |
||||||
|
try { Tasks.await(task); } catch (ExecutionException | InterruptedException ignore) {} |
||||||
|
assertTrue(task.isComplete()); |
||||||
|
assertFalse(task.isSuccessful()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRunRunnable_background() { |
||||||
|
WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.run(getRunnableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRunRunnable_sameThread() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op1 = new Op<>(true); |
||||||
|
final Op<Boolean> op2 = new Op<>(true); |
||||||
|
handler.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
handler.run(getRunnableForOp(op2)); |
||||||
|
assertTrue(op2.await(0)); // Do not wait.
|
||||||
|
op1.end(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
waitOp(op1); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRunCallable_background() { |
||||||
|
WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.run(getCallableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRunCallable_sameThread() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op1 = new Op<>(true); |
||||||
|
final Op<Boolean> op2 = new Op<>(true); |
||||||
|
handler.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
handler.run(getCallableForOp(op2)); |
||||||
|
assertTrue(op2.await(0)); // Do not wait.
|
||||||
|
op1.end(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
waitOp(op1); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRunCallable_sameThread_throws() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.post(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
Task<Void> task = handler.run(getThrowCallable()); |
||||||
|
assertTrue(task.isComplete()); // Already complete
|
||||||
|
assertFalse(task.isSuccessful()); |
||||||
|
op.end(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPostDelayed_tooEarly() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.post(1000, getRunnableForOp(op)); |
||||||
|
assertNull(op.await(500)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPostDelayed() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
handler.post(1000, getRunnableForOp(op)); |
||||||
|
assertNotNull(op.await(2000)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRemove() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
Runnable runnable = getRunnableForOp(op); |
||||||
|
handler.post(1000, runnable); |
||||||
|
handler.remove(runnable); |
||||||
|
assertNull(op.await(2000)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGetters() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
assertNotNull(handler.getExecutor()); |
||||||
|
assertNotNull(handler.getHandler()); |
||||||
|
assertNotNull(handler.getLooper()); |
||||||
|
assertNotNull(handler.getThread()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testExecutor() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
Executor executor = handler.getExecutor(); |
||||||
|
final Op<Boolean> op = new Op<>(true); |
||||||
|
executor.execute(getRunnableForOp(op)); |
||||||
|
waitOp(op); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testDestroy() { |
||||||
|
final WorkerHandler handler = WorkerHandler.get("handler"); |
||||||
|
assertTrue(handler.getThread().isAlive()); |
||||||
|
WorkerHandler.destroy(); |
||||||
|
// Wait for the thread to die.
|
||||||
|
try { handler.getThread().join(500); } catch (InterruptedException ignore) {} |
||||||
|
assertFalse(handler.getThread().isAlive()); |
||||||
|
WorkerHandler newHandler = WorkerHandler.get("handler"); |
||||||
|
assertNotSame(handler, newHandler); |
||||||
|
assertTrue(newHandler.getThread().isAlive()); |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,104 @@ |
|||||||
|
package com.otaliastudios.cameraview.markers; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.PointF; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
|
||||||
|
import androidx.test.annotation.UiThreadTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Rule; |
||||||
|
import org.junit.Test; |
||||||
|
import org.mockito.Mockito; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
import static org.mockito.Mockito.atLeastOnce; |
||||||
|
import static org.mockito.Mockito.mock; |
||||||
|
import static org.mockito.Mockito.never; |
||||||
|
import static org.mockito.Mockito.spy; |
||||||
|
import static org.mockito.Mockito.verify; |
||||||
|
|
||||||
|
public class DefaultAutoFocusMarkerTest extends BaseTest { |
||||||
|
|
||||||
|
private DefaultAutoFocusMarker marker; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
marker = new DefaultAutoFocusMarker(); |
||||||
|
} |
||||||
|
|
||||||
|
@After |
||||||
|
public void tearDown() { |
||||||
|
marker = null; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testOnAttach() { |
||||||
|
assertNull(marker.mContainer); |
||||||
|
assertNull(marker.mFill); |
||||||
|
ViewGroup container = new FrameLayout(getContext()); |
||||||
|
View result = marker.onAttach(getContext(), container); |
||||||
|
assertNotNull(result); |
||||||
|
assertNotNull(marker.mContainer); |
||||||
|
assertNotNull(marker.mFill); |
||||||
|
} |
||||||
|
|
||||||
|
@UiThreadTest |
||||||
|
@Test |
||||||
|
public void testOnAutoFocusStart() { |
||||||
|
View mockContainer = spy(new View(getContext())); |
||||||
|
View mockFill = spy(new View(getContext())); |
||||||
|
marker.mContainer = mockContainer; |
||||||
|
marker.mFill = mockFill; |
||||||
|
marker.onAutoFocusStart(AutoFocusTrigger.GESTURE, new PointF()); |
||||||
|
verify(mockContainer, atLeastOnce()).clearAnimation(); |
||||||
|
verify(mockFill, atLeastOnce()).clearAnimation(); |
||||||
|
verify(mockContainer, atLeastOnce()).animate(); |
||||||
|
verify(mockFill, atLeastOnce()).animate(); |
||||||
|
} |
||||||
|
|
||||||
|
@UiThreadTest |
||||||
|
@Test |
||||||
|
public void testOnAutoFocusStart_fromMethod() { |
||||||
|
View mockContainer = spy(new View(getContext())); |
||||||
|
View mockFill = spy(new View(getContext())); |
||||||
|
marker.mContainer = mockContainer; |
||||||
|
marker.mFill = mockFill; |
||||||
|
marker.onAutoFocusStart(AutoFocusTrigger.METHOD, new PointF()); |
||||||
|
verify(mockContainer, never()).clearAnimation(); |
||||||
|
verify(mockFill, never()).clearAnimation(); |
||||||
|
verify(mockContainer, never()).animate(); |
||||||
|
verify(mockFill, never()).animate(); |
||||||
|
} |
||||||
|
|
||||||
|
@UiThreadTest |
||||||
|
@Test |
||||||
|
public void testOnAutoFocusEnd() { |
||||||
|
View mockContainer = spy(new View(getContext())); |
||||||
|
View mockFill = spy(new View(getContext())); |
||||||
|
marker.mContainer = mockContainer; |
||||||
|
marker.mFill = mockFill; |
||||||
|
marker.onAutoFocusEnd(AutoFocusTrigger.GESTURE, true, new PointF()); |
||||||
|
verify(mockContainer, atLeastOnce()).animate(); |
||||||
|
verify(mockFill, atLeastOnce()).animate(); |
||||||
|
} |
||||||
|
|
||||||
|
@UiThreadTest |
||||||
|
@Test |
||||||
|
public void testOnAutoFocusEnd_fromMethod() { |
||||||
|
View mockContainer = spy(new View(getContext())); |
||||||
|
View mockFill = spy(new View(getContext())); |
||||||
|
marker.mContainer = mockContainer; |
||||||
|
marker.mFill = mockFill; |
||||||
|
marker.onAutoFocusEnd(AutoFocusTrigger.METHOD, true, new PointF()); |
||||||
|
verify(mockContainer, never()).animate(); |
||||||
|
verify(mockFill, never()).animate(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
package com.otaliastudios.cameraview.markers; |
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.PointF; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
import androidx.annotation.StyleableRes; |
||||||
|
import androidx.arch.core.util.Function; |
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
|
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
import com.otaliastudios.cameraview.R; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
import com.otaliastudios.cameraview.size.SizeSelectorParser; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertNotNull; |
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean; |
||||||
|
import static org.mockito.ArgumentMatchers.anyInt; |
||||||
|
import static org.mockito.ArgumentMatchers.eq; |
||||||
|
import static org.mockito.Mockito.mock; |
||||||
|
import static org.mockito.Mockito.when; |
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class MarkerParserTest extends BaseTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testNullConstructor() { |
||||||
|
TypedArray array = mock(TypedArray.class); |
||||||
|
when(array.hasValue(R.styleable.CameraView_cameraAutoFocusMarker)).thenReturn(false); |
||||||
|
when(array.getString(R.styleable.CameraView_cameraAutoFocusMarker)).thenReturn(null); |
||||||
|
MarkerParser parser = new MarkerParser(array); |
||||||
|
assertNull(parser.getAutoFocusMarker()); |
||||||
|
} |
||||||
|
@Test |
||||||
|
public void testConstructor() { |
||||||
|
TypedArray array = mock(TypedArray.class); |
||||||
|
when(array.hasValue(R.styleable.CameraView_cameraAutoFocusMarker)).thenReturn(true); |
||||||
|
when(array.getString(R.styleable.CameraView_cameraAutoFocusMarker)).thenReturn(Marker.class.getName()); |
||||||
|
MarkerParser parser = new MarkerParser(array); |
||||||
|
assertNotNull(parser.getAutoFocusMarker()); |
||||||
|
assertTrue(parser.getAutoFocusMarker() instanceof Marker); |
||||||
|
} |
||||||
|
|
||||||
|
public static class Marker implements AutoFocusMarker { |
||||||
|
|
||||||
|
public Marker() { } |
||||||
|
|
||||||
|
@Nullable |
||||||
|
@Override |
||||||
|
public View onAttach(@NonNull Context context, @NonNull ViewGroup container) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAutoFocusStart(@NonNull AutoFocusTrigger trigger, @NonNull PointF point) { } |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAutoFocusEnd(@NonNull AutoFocusTrigger trigger, boolean successful, @NonNull PointF point) { } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,211 @@ |
|||||||
|
package com.otaliastudios.cameraview.size; |
||||||
|
|
||||||
|
|
||||||
|
import android.content.res.TypedArray; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.StyleableRes; |
||||||
|
import androidx.arch.core.util.Function; |
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4; |
||||||
|
import androidx.test.filters.SmallTest; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.BaseTest; |
||||||
|
import com.otaliastudios.cameraview.R; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean; |
||||||
|
import static org.mockito.ArgumentMatchers.anyInt; |
||||||
|
import static org.mockito.ArgumentMatchers.eq; |
||||||
|
import static org.mockito.Mockito.mock; |
||||||
|
import static org.mockito.Mockito.when; |
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class SizeSelectorParserTest extends BaseTest { |
||||||
|
|
||||||
|
private MockTypedArray input; |
||||||
|
private List<Size> sizes = Arrays.asList( |
||||||
|
new Size(100, 200), |
||||||
|
new Size(150, 300), |
||||||
|
new Size(600, 900), |
||||||
|
new Size(600, 600), |
||||||
|
new Size(1600, 900), |
||||||
|
new Size(30, 40), |
||||||
|
new Size(40, 30), |
||||||
|
new Size(2000, 4000) |
||||||
|
); |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
input = new MockTypedArray(); |
||||||
|
} |
||||||
|
|
||||||
|
@After |
||||||
|
public void tearDown() { |
||||||
|
input = null; |
||||||
|
} |
||||||
|
|
||||||
|
private void doAssert(@NonNull Function<List<Size>, Void> assertions) { |
||||||
|
SizeSelectorParser parser = new SizeSelectorParser(input.array); |
||||||
|
assertions.apply(parser.getPictureSizeSelector().select(sizes)); |
||||||
|
assertions.apply(parser.getVideoSizeSelector().select(sizes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testWidth() { |
||||||
|
input.setMinWidth(1500); |
||||||
|
input.setMaxWidth(1700); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(1, input.size()); |
||||||
|
assertEquals(new Size(1600, 900), input.get(0)); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testHeight() { |
||||||
|
input.setMinHeight(25); |
||||||
|
input.setMaxHeight(35); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(1, input.size()); |
||||||
|
assertEquals(new Size(40, 30), input.get(0)); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testArea() { |
||||||
|
input.setMinArea(30 * 30); |
||||||
|
input.setMaxArea(40 * 40); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(2, input.size()); |
||||||
|
assertTrue(input.contains(new Size(40, 30))); |
||||||
|
assertTrue(input.contains(new Size(30, 40))); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testSmallest() { |
||||||
|
input.setSmallest(true); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(sizes.size(), input.size()); |
||||||
|
Size first = input.get(0); |
||||||
|
assertEquals(30 * 40, first.getWidth() * first.getHeight()); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testBiggest() { |
||||||
|
input.setBiggest(true); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(sizes.size(), input.size()); |
||||||
|
assertEquals(new Size(2000, 4000), input.get(0)); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAspectRatio() { |
||||||
|
input.setAspectRatio("16:9"); |
||||||
|
doAssert(new Function<List<Size>, Void>() { |
||||||
|
@Override |
||||||
|
public Void apply(List<Size> input) { |
||||||
|
assertEquals(1, input.size()); |
||||||
|
assertEquals(new Size(1600, 900), input.get(0)); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue") |
||||||
|
private class MockTypedArray { |
||||||
|
private TypedArray array = mock(TypedArray.class); |
||||||
|
|
||||||
|
private void setIntValue(@StyleableRes int index, int value) { |
||||||
|
when(array.hasValue(index)).thenReturn(true); |
||||||
|
when(array.getInteger(eq(index), anyInt())).thenReturn(value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setBooleanValue(@StyleableRes int index, boolean value) { |
||||||
|
when(array.hasValue(index)).thenReturn(true); |
||||||
|
when(array.getBoolean(eq(index), anyBoolean())).thenReturn(value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setStringValue(@StyleableRes int index, @NonNull String value) { |
||||||
|
when(array.hasValue(index)).thenReturn(true); |
||||||
|
when(array.getString(index)).thenReturn(value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMinWidth(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMinWidth, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMinWidth, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMaxWidth(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxWidth, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxWidth, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMinHeight(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMinHeight, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMinHeight, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMaxHeight(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxHeight, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxHeight, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMinArea(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMinArea, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMinArea, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setMaxArea(int value) { |
||||||
|
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxArea, value); |
||||||
|
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxArea, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setSmallest(boolean value) { |
||||||
|
setBooleanValue(R.styleable.CameraView_cameraPictureSizeSmallest, value); |
||||||
|
setBooleanValue(R.styleable.CameraView_cameraVideoSizeSmallest, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setBiggest(boolean value) { |
||||||
|
setBooleanValue(R.styleable.CameraView_cameraPictureSizeBiggest, value); |
||||||
|
setBooleanValue(R.styleable.CameraView_cameraVideoSizeBiggest, value); |
||||||
|
} |
||||||
|
|
||||||
|
private void setAspectRatio(@NonNull String value) { |
||||||
|
setStringValue(R.styleable.CameraView_cameraPictureSizeAspectRatio, value); |
||||||
|
setStringValue(R.styleable.CameraView_cameraVideoSizeAspectRatio, value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
package com.otaliastudios.cameraview.internal.utils; |
||||||
|
|
||||||
|
|
||||||
|
import androidx.exifinterface.media.ExifInterface; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static junit.framework.Assert.assertNotNull; |
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertFalse; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
|
||||||
|
public class ExifHelperTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testValues() { |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_NORMAL)); |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_FLIP_HORIZONTAL)); |
||||||
|
assertEquals(180, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_ROTATE_180)); |
||||||
|
assertEquals(180, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_FLIP_VERTICAL)); |
||||||
|
assertEquals(90, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_ROTATE_90)); |
||||||
|
assertEquals(90, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_TRANSPOSE)); |
||||||
|
assertEquals(270, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_ROTATE_270)); |
||||||
|
assertEquals(270, ExifHelper.readExifOrientation(ExifInterface.ORIENTATION_TRANSVERSE)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testUnknownValues() { |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(-15)); |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(-1)); |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(195)); |
||||||
|
assertEquals(0, ExifHelper.readExifOrientation(Integer.MAX_VALUE)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue